From 6ad5e1c013a0d56d440e4c0722af56a3a6859dfc Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Thu, 1 Oct 2020 15:07:25 -0400 Subject: [PATCH] Fix #4264 - prevent crash when analysing file with duplicate classes --- .../Internal/PhpVisitor/ReflectorVisitor.php | 12 +++++++++- tests/IncludeTest.php | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php index 22ac8dae5..22c3f5f60 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -146,6 +146,11 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse */ private $classlike_type_aliases = []; + /** + * @var array + */ + private $bad_classes = []; + public function __construct( Codebase $codebase, FileStorage $file_storage, @@ -285,7 +290,8 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse } if ($this->registerClassLike($node) === false) { - return PhpParser\NodeTraverser::STOP_TRAVERSAL; + $this->bad_classes[\spl_object_id($node)] = true; + return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN; } } elseif (($node instanceof PhpParser\Node\Expr\New_ || $node instanceof PhpParser\Node\Expr\Instanceof_ @@ -575,6 +581,10 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse return null; } + if (isset($this->bad_classes[\spl_object_id($node)])) { + return null; + } + if (!$this->fq_classlike_names) { throw new \LogicException('$this->fq_classlike_names should not be empty'); } diff --git a/tests/IncludeTest.php b/tests/IncludeTest.php index 63c2ca022..16ab53323 100644 --- a/tests/IncludeTest.php +++ b/tests/IncludeTest.php @@ -599,6 +599,28 @@ class IncludeTest extends TestCase getcwd() . DIRECTORY_SEPARATOR . 'file2.php', ], ], + 'noCrash' => [ + 'files' => [ + getcwd() . DIRECTORY_SEPARATOR . 'classes.php' => ' ' [ + getcwd() . DIRECTORY_SEPARATOR . 'user.php', + ], + ], ]; }