Skip to content

Commit

Permalink
Merge pull request #10050 from jrfnl/feature/10037-classmapgenerator-…
Browse files Browse the repository at this point in the history
…bug-fixes

ClassMapGenerator: fix two bugs (long heredocs + markers in text)
  • Loading branch information
Seldaek committed Aug 12, 2021
2 parents c65bd83 + 42c6a0d commit 4da1a2d
Show file tree
Hide file tree
Showing 8 changed files with 2,229 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Composer/Autoload/ClassMapGenerator.php
Expand Up @@ -246,7 +246,7 @@ private static function findClasses($path)
}

// strip heredocs/nowdocs
$contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)(?:\s*)\\2(?=\s+|[;,.)])}s', 'null', $contents);
$contents = preg_replace('{<<<[ \t]*([\'"]?)(\w+)\\1(?:\r\n|\n|\r)(?:.*(?=[\r\n]+[ \t]*\\2))[\r\n]+[ \t]*\\2(?=\s*[;,.)])}s', 'null', $contents);
// strip strings
$contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);
// strip leading non-php code if needed
Expand Down
19 changes: 19 additions & 0 deletions tests/Composer/Test/Autoload/ClassMapGeneratorTest.php
Expand Up @@ -244,6 +244,25 @@ public function testDump()
$fs->removeDirectory($tempDir);
}

public function testCreateMapDoesNotHitRegexBacktraceLimit()
{
$expected = array(
'Foo\\StripNoise' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/StripNoise.php',
'Foo\\VeryLongHeredoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongHeredoc.php',
'Foo\\ClassAfterLongHereDoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongHeredoc.php',
'Foo\\VeryLongPHP73Heredoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongPHP73Heredoc.php',
'Foo\\VeryLongPHP73Nowdoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongPHP73Nowdoc.php',
'Foo\\ClassAfterLongNowDoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongPHP73Nowdoc.php',
'Foo\\VeryLongNowdoc' => realpath(__DIR__) . '/Fixtures/pcrebacktracelimit/VeryLongNowdoc.php',
);

ini_set('pcre.backtrack_limit', '30000');
$result = ClassMapGenerator::createMap(__DIR__ . '/Fixtures/pcrebacktracelimit');
ini_restore('pcre.backtrack_limit');

$this->assertEqualsNormalized($expected, $result);
}

protected function assertEqualsNormalized($expected, $actual, $message = '')
{
foreach ($expected as $ns => $path) {
Expand Down
Expand Up @@ -17,7 +17,12 @@ class FailHeredocBasic
class FailHeredocWhitespace
{
}
WHITESPACE . <<<"DOUBLEQUOTES"
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.
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
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
@@ -0,0 +1,87 @@
<?php

namespace Foo;

/**
* class StripNoise { }
*/
class StripNoise
{
public function test_heredoc()
{
return <<<HEREDOC
class FailHeredocBasic
{
}
HEREDOC . <<< WHITESPACE
class FailHeredocWhitespace
{
}
WHITESPACE . <<<"DOUBLEQUOTES"
class FailHeredocDoubleQuotes
{
}
DOUBLEQUOTES . <<< "DOUBLEQUOTESTABBED"
class FailHeredocDoubleQuotesTabbed
{
}
DOUBLEQUOTESTABBED . <<<HEREDOCPHP73
class FailHeredocPHP73
{
}
HEREDOCPHP73;
}

public function test_nowdoc()
{
return <<<'NOWDOC'
class FailNowdocBasic
{
}
NOWDOC . <<< 'WHITESPACE'
class FailNowdocWhitespace
{
}
WHITESPACE . <<< 'NOWDOCTABBED'
class FailNowdocTabbed
{
}
NOWDOCTABBED . <<<'NOWDOCPHP73'
class FailNowdocPHP73
{
}
NOWDOCPHP73;
}

public function test_followed_by_parentheses()
{
return array(<<<PARENTHESES
class FailParentheses
{
}
PARENTHESES);
}

public function test_followed_by_comma()
{
return array(1, 2, <<<COMMA
class FailComma
{
}
COMMA, 3, 4);
}

public function test_followed_by_period()
{
return <<<PERIOD
class FailPeriod
{
}
PERIOD.'?>';
}

public function test_simple_string()
{
return 'class FailSimpleString {}';
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

0 comments on commit 4da1a2d

Please sign in to comment.