Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop into out of memory error for class wrongfully extending itself #7787

Closed
FO-nTTaX opened this issue Aug 13, 2022 · 8 comments
Closed
Labels

Comments

@FO-nTTaX
Copy link

Bug report

When creating a class that extends itself, phpstan will infinitely loop on trying to get the parent class until it is out of memory. I understand this is not valid php code, but I wonder if this might be catch-able and if this could be a normal error with an error message.

Code snippet that reproduces the problem

<?php
class TestClass extends TestClass {}

The share link on phpstan.org does not work because this breaks phpstan pretty badly.

Expected output

This code snippet produces an out of memory error, ideally it should probably create an error message that a class cannot extend itself.

Did PHPStan help you today? Did it make you happy in any way?

phpstan helps me all the time telling me when I made stupid typos, this tool is amazing :)

@mergeable
Copy link

mergeable bot commented Aug 13, 2022

This bug report is missing a link to reproduction at phpstan.org/try.

It will most likely be closed after manual review.

@herndlm
Copy link
Contributor

herndlm commented Aug 14, 2022

This seems to be coming from PHPStan\BetterReflection\Reflection\ReflectionClass::getParentClass() or respectively internally from getInheritanceClassHierarchy. The fix should be simple, but I noticed that the upstream lib and the fork have deviated in general. Shall I try to reproduce it upstream and report/fix there or is another approach preferred?

On the other hand this is indeed invalid PHP code not true (https://3v4l.org/360uT, it just can't find the class), so I'm not sure if Better Reflection "supports" that or if we should rather avoid here that it get so far in the first place. UPDATE: fixing it here might be tricky, e.g. I avoided it in one place, it happened in another one. Most likely that's not the best solution then. I'll later try to reproduce and fix it directly in Better Reflection if that's fine.

Also, the same thing is happening with interfaces as well, e.g. interface Foo extends Foo {}

traceback
1) PHPStan\Analyser\AnalyserIntegrationTest::testBug7787
Error: Xdebug has detected a possible infinite loop, and aborted your script with a stack depth of '256' frames

/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php:1032
/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php:1669
/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php:1672 ---- printed x times ---
/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php:1399
/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.php:1563
/home/martin/PhpstormProjects/phpstan-src/vendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionClass.php:337
/home/martin/PhpstormProjects/phpstan-src/src/Reflection/ClassReflection.php:758
/home/martin/PhpstormProjects/phpstan-src/src/Reflection/ClassReflection.php:709
/home/martin/PhpstormProjects/phpstan-src/src/Dependency/DependencyResolver.php:229
/home/martin/PhpstormProjects/phpstan-src/src/Dependency/DependencyResolver.php:45
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/FileAnalyser.php:159
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/NodeScopeResolver.php:381
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/NodeScopeResolver.php:284
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/NodeScopeResolver.php:614
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/NodeScopeResolver.php:243
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/FileAnalyser.php:178
/home/martin/PhpstormProjects/phpstan-src/src/Analyser/Analyser.php:70
/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/AnalyserIntegrationTest.php:925
/home/martin/PhpstormProjects/phpstan-src/tests/PHPStan/Analyser/AnalyserIntegrationTest.php:871

@FO-nTTaX
Copy link
Author

So I haven't tested it, but something maybe worth looking into is circular extends between multiple classes, as that might lead to the same issue?

@herndlm
Copy link
Contributor

herndlm commented Aug 14, 2022

Yes, that's basically the core problem. Circular extends between one or more classes

@ondrejmirtes
Copy link
Member

There are many similar problems that are not prevented in PHPStan:

  • Circular extends between classes
  • Circular extends between interfaces
  • Circular uses between traits
  • The same problem maybe between the wrong types, like classes extending interfaces

And the same problems will cause infinite recursions in different places in the codebase for generics - where @extends, @implements, @uses are involved.

If the problem can be prevented by throwing an exception in BetterReflection, I'm all for it. I'll then rebase my own fork on top of the latest branch.

@ondrejmirtes
Copy link
Member

And while we're at it, there are also constants and class constants whose values can reference themselves in a circular fashion.

In BetterReflection that should be detected and prevented in CompileNodeToValue.

But PHPStan doesn't use that. Here it should be prevented in InitializerExprTypeResolver.

@ondrejmirtes
Copy link
Member

This is fixed now thanks to update to BetterReflection 6.0. It will produce this message: "Reflection error: Circular reference to class "Bug7787\TestClass""

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants