From e333ccc9f6b0ce3417b1148652215d44e8d4e5ef Mon Sep 17 00:00:00 2001 From: ju1ius Date: Fri, 20 May 2022 23:32:48 +0200 Subject: [PATCH] Fixes `CallExpression::reflectCallable()` throwing `TypeError` --- src/Node/Expression/CallExpression.php | 7 ++++++- tests/Node/Expression/CallTest.php | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Node/Expression/CallExpression.php b/src/Node/Expression/CallExpression.php index a3b7c7e0d..43ee51ddf 100644 --- a/src/Node/Expression/CallExpression.php +++ b/src/Node/Expression/CallExpression.php @@ -290,7 +290,12 @@ abstract class CallExpression extends AbstractExpression } $checkVisibility = $callable instanceof \Closure; - $r = new \ReflectionFunction(\Closure::fromCallable($callable)); + try { + $closure = \Closure::fromCallable($callable); + } catch (\TypeError $e) { + throw new \LogicException(sprintf('Callback for %s "%s" is not callable in the current scope.', $this->getAttribute('type'), $this->getAttribute('name')), 0, $e); + } + $r = new \ReflectionFunction($closure); if (false !== strpos($r->name, '{closure}')) { return $this->reflector = [$r, $callable, 'Closure']; diff --git a/tests/Node/Expression/CallTest.php b/tests/Node/Expression/CallTest.php index 0e66f0d3f..0f21cb33e 100644 --- a/tests/Node/Expression/CallTest.php +++ b/tests/Node/Expression/CallTest.php @@ -94,6 +94,15 @@ class CallTest extends TestCase $this->getArguments($node, [[$this, 'customFunctionWithArbitraryArguments'], []]); } + public function testGetArgumentsWithInvalidCallable() + { + // see https://github.com/twigphp/Twig/issues/3708 + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Callback for function "foo" is not callable in the current scope.'); + $node = new Node_Expression_Call([], ['type' => 'function', 'name' => 'foo', 'is_variadic' => true]); + $this->getArguments($node, ['', []]); + } + public static function customStaticFunction($arg1, $arg2 = 'default', $arg3 = []) { }