Skip to content

PCRE problem #4448

@b1rdex

Description

@b1rdex

Bug report

We got a PHP error after upgrading to PHP 8:

TypeError: preg_replace(): Argument #3 ($subject) must be of type array|string, null given in phpstan-src/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php:207
   
   #0 phpstan-src/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php:207 preg_replace()
   #1 phpstan-src/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php:168 PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedDirectorySourceLocator->findSymbols()
   #2 phpstan-src/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php:130 PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedDirectorySourceLocator->init()
   #3 phpstan-src/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php:57 PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedDirectorySourceLocator->findFileByClass()
   #4 phpstan-src/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.php:35 PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedDirectorySourceLocator->locateIdentifier()
   #5 phpstan-src/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php:40 Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator->locateIdentifier()
   #6 phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflector/ClassReflector.php:45 Roave\BetterReflection\SourceLocator\Type\MemoizingSourceLocator->locateIdentifier()
   #7 phpstan-src/src/Reflection/BetterReflection/Reflector/MemoizingClassReflector.php:32 Roave\BetterReflection\Reflector\ClassReflector->reflect()
   #8 phpstan-src/src/Reflection/BetterReflection/BetterReflectionProvider.php:118 PHPStan\Reflection\BetterReflection\Reflector\MemoizingClassReflector->reflect()
   #9 phpstan-src/src/Reflection/ReflectionProvider/ChainReflectionProvider.php:30 PHPStan\Reflection\BetterReflection\BetterReflectionProvider->hasClass()
   #10 phpstan-src/src/Reflection/ReflectionProvider/MemoizingReflectionProvider.php:37 PHPStan\Reflection\ReflectionProvider\ChainReflectionProvider->hasClass()
   #11 phpstan-src/src/Broker/Broker.php:63 PHPStan\Reflection\ReflectionProvider\MemoizingReflectionProvider->hasClass()
   #12 phpstan-src/src/Type/ObjectType.php:281 PHPStan\Broker\Broker->hasClass()
   #13 phpstan-src/src/Type/VerbosityLevel.php:93 PHPStan\Type\ObjectType->PHPStan\Type\{closure}()
   #14 phpstan-src/src/Type/ObjectType.php:297 PHPStan\Type\VerbosityLevel->handle()
   #15 phpstan-src/src/Command/IgnoredRegexValidator.php:90 PHPStan\Type\ObjectType->describe()
   #16 phpstan-src/src/Command/IgnoredRegexValidator.php:50 PHPStan\Command\IgnoredRegexValidator->getIgnoredTypes()
   #17 phpstan-src/src/Analyser/IgnoredErrorHelper.php:89 PHPStan\Command\IgnoredRegexValidator->validate()
   #18 phpstan-src/src/Command/AnalyseApplication.php:92 PHPStan\Analyser\IgnoredErrorHelper->initialize()
   #19 phpstan-src/src/Command/AnalyseCommand.php:228 PHPStan\Command\AnalyseApplication->analyse()
   #20 phpstan-src/vendor/symfony/console/Command/Command.php:255 PHPStan\Command\AnalyseCommand->execute()
   #21 phpstan-src/vendor/symfony/console/Application.php:1009 Symfony\Component\Console\Command\Command->run()
   #22 phpstan-src/vendor/symfony/console/Application.php:273 Symfony\Component\Console\Application->doRunCommand()
   #23 phpstan-src/vendor/symfony/console/Application.php:149 Symfony\Component\Console\Application->doRun()
   #24 phpstan-src/bin/phpstan(96): Symfony\Component\Console\Application->run()
   #25 phpstan-src/bin/phpstan(97): {closure}()

The problem is here: https://github.com/phpstan/phpstan-src/blob/b9f1d99dcdb2dfc738f20ac1c6a579fe6c1cb16f/src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php#L205

I added some debug statements and found that PCRE error was "Backtrack limit exhausted". We're on defaults, and it's 1000000 (same as on 7.4).

I had to set it to -1 to fix this. Here is the cause: https://gist.github.com/b1rdex/97698460e26b51f416b78d9c64b14bfd/7b9926f0c6e7f4363c3550b7b9ded8769903bd5d. It contains a very big heredoc.

The PCRE might be doing catastrophic backtracking. I can't fix it.

Please add some is_string() checks and report the error correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions