Skip to content

Commit eda9f5f

Browse files
committed
Fix Closure::call() on internal method closure
In this case we should use the original internal handler. Otherwise the trampoline will attempt to free the closure, but the function being used is not actually part of a closure anymore.
1 parent 526407c commit eda9f5f

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

Zend/tests/closure_call_internal.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Closure::call() on internal method
3+
--FILE--
4+
<?php
5+
6+
var_dump(Closure::fromCallable([new DateTime(), 'getTimestamp'])->call(new DateTime('@123')));
7+
8+
?>
9+
--EXPECT--
10+
int(123)

Zend/zend_closures.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ ZEND_METHOD(Closure, call)
152152
my_function.common.fn_flags &= ~ZEND_ACC_CLOSURE;
153153
/* use scope of passed object */
154154
my_function.common.scope = Z_OBJCE_P(newthis);
155+
if (closure->func.type == ZEND_INTERNAL_FUNCTION) {
156+
my_function.internal_function.handler = closure->orig_internal_handler;
157+
}
155158
fci_cache.function_handler = &my_function;
156159

157160
/* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */

0 commit comments

Comments
 (0)