Skip to content

Commit

Permalink
Merge pull request #10072 from jrfnl/feature/10067-fix-classmap-regre…
Browse files Browse the repository at this point in the history
…ssion

ClassMapGenerator: stabilize the heredoc/nowdoc stripping
  • Loading branch information
Seldaek committed Aug 29, 2021
2 parents 73c109c + d8054d1 commit 922ba01
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
17 changes: 16 additions & 1 deletion src/Composer/Autoload/ClassMapGenerator.php
Expand Up @@ -246,7 +246,22 @@ private static function findClasses($path)
}

// strip heredocs/nowdocs
$contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*(?=[\r\n]+[ \t]*\\2))[\r\n]+[ \t]*\\2(?=\s*[;,.)])}s', 'null', $contents);
$contents = preg_replace('{
# opening heredoc/nowdoc delimiter (word-chars)
<<<[ \t]*+([\'"]?)(\w++)\\1
# needs to be followed by a newline
(?:\r\n|\n|\r)
# the meat of it, matching line by line until end delimiter
(?:
# a valid line is optional white-space (possessive match) not followed by the end delimiter, then anything goes for the rest of the line
[\t ]*+(?!\\2 \b)[^\r\n]*+
# end of line(s)
[\r\n]++
)*
# end delimiter
[\t ]*+ \\2 (?=\b)
}xu', 'null', $contents);

// strip strings
$contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);
// strip leading non-php code if needed
Expand Down
3 changes: 3 additions & 0 deletions tests/Composer/Test/Autoload/ClassMapGeneratorTest.php
Expand Up @@ -55,6 +55,9 @@ public function getTestCreateMapTests()
'Foo\\LargeGap' => realpath(__DIR__) . '/Fixtures/classmap/LargeGap.php',
'Foo\\MissingSpace' => realpath(__DIR__) . '/Fixtures/classmap/MissingSpace.php',
'Foo\\StripNoise' => realpath(__DIR__) . '/Fixtures/classmap/StripNoise.php',
'Foo\\First' => realpath(__DIR__) . '/Fixtures/classmap/StripNoise.php',
'Foo\\Second' => realpath(__DIR__) . '/Fixtures/classmap/StripNoise.php',
'Foo\\Third' => realpath(__DIR__) . '/Fixtures/classmap/StripNoise.php',
'Foo\\SlashedA' => realpath(__DIR__) . '/Fixtures/classmap/BackslashLineEndingString.php',
'Foo\\SlashedB' => realpath(__DIR__) . '/Fixtures/classmap/BackslashLineEndingString.php',
'Unicode\\↑\\↑' => realpath(__DIR__) . '/Fixtures/classmap/Unicode.php',
Expand Down
59 changes: 58 additions & 1 deletion tests/Composer/Test/Autoload/Fixtures/classmap/StripNoise.php
Expand Up @@ -19,8 +19,14 @@ class FailHeredocWhitespace
}
WHITESPACE . <<< MARKERINTEXT
In PHP < 7.3, the docblock marker could occur in the text as long as it did not occur at the very start of the line.
class FailHeredocMarkerInText
{
}
But, what are you blind McFly, it's there. How else do you explain that wreck out there? Doc, Doc. Oh, no. You're alive. Bullet proof vest, how did you know, I never got a chance to tell you. About all that talk about screwing up future events, the space time continuum. Okay, alright, I'll prove it to you.
MARKERINTEXT
. MARKERINTEXT
class FailHeredocMarkerInText2
{
}
Look at my driver's license, expires 1987. Look at my birthday, for crying out load I haven't even been born yet. And, look at this picture, my brother, my sister, and me. Look at the sweatshirt, Doc, class of 1984. Why do you keep following me around? Hey beat it, spook, this don't concern you.
MARKERINTEXT . <<<"DOUBLEQUOTES"
class FailHeredocDoubleQuotes
Expand Down Expand Up @@ -89,4 +95,55 @@ public function test_simple_string()
{
return 'class FailSimpleString {}';
}

public function test_unicode_heredoc()
{
return array(1, 2, <<<öéçив必
class FailUnicode
{
}
öéçив必, 3, 4);
}

public function test_wrapped_in_curly_brackets()
{
return ${<<<FOO
class FailCurlyBrackets
{
}
FOO};
}
public function test_wrapped_in_angle_brackets()
{
return [<<<FOO
class FailAngleBrackets
{
}
FOO];
}
}

// Issue #10067.
abstract class First {
public function heredocDuplicateMarker(): void {
echo <<<DUPLICATE_MARKER

DUPLICATE_MARKER;
}
}

abstract class Second extends First {
public function heredocDuplicateMarker(): void {
echo <<<DUPLICATE_MARKER

DUPLICATE_MARKER;
}
}

abstract class Third extends First {
public function heredocMarkersOnlyWhitespaceBetween(): void {
echo <<<DUPLICATE_MARKER
DUPLICATE_MARKER;
}
}

0 comments on commit 922ba01

Please sign in to comment.