From cc7ff94f7cc62ade9b307828ad6e17caa2aa9123 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Thu, 13 May 2021 12:40:39 -0400 Subject: [PATCH] Prevent crash when method being called does not exist in reflection Crash seen when running this test in PHP 7.4 because the method does not exist, but the call map includes it in 8.0 --- src/Psalm/Internal/Analyzer/MethodAnalyzer.php | 4 ++++ .../Call/Method/MethodVisibilityAnalyzer.php | 4 ++++ src/Psalm/Internal/Codebase/Methods.php | 4 ++++ tests/MethodCallTest.php | 15 +++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php index 8f66aad06..1657700cd 100644 --- a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php @@ -87,6 +87,10 @@ class MethodAnalyzer extends FunctionLikeAnalyzer $method_id = $codebase_methods->getDeclaringMethodId($method_id); if (!$method_id) { + if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $original_method_id)) { + return true; + } + throw new \LogicException('Declaring method for ' . $original_method_id . ' should not be null'); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php index af34fe022..e07479f85 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php @@ -69,6 +69,10 @@ class MethodVisibilityAnalyzer return null; } + if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id)) { + return null; + } + throw new \UnexpectedValueException('$declaring_method_id not expected to be null here'); } diff --git a/src/Psalm/Internal/Codebase/Methods.php b/src/Psalm/Internal/Codebase/Methods.php index 0a7994444..dd82c6625 100644 --- a/src/Psalm/Internal/Codebase/Methods.php +++ b/src/Psalm/Internal/Codebase/Methods.php @@ -1101,6 +1101,10 @@ class Methods $declaring_method_id = $this->getDeclaringMethodId($method_id); if (!$declaring_method_id) { + if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id)) { + return null; + } + throw new \UnexpectedValueException('$storage should not be null for ' . $method_id); } diff --git a/tests/MethodCallTest.php b/tests/MethodCallTest.php index d4272c503..cfcda3a8f 100644 --- a/tests/MethodCallTest.php +++ b/tests/MethodCallTest.php @@ -969,6 +969,21 @@ class MethodCallTest extends TestCase } }' ], + 'noCrashWhenCallingParent' => [ + '