Skip to content

Commit

Permalink
Fix Closure::call() on internal method closure
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Aug 27, 2021
1 parent 526407c commit eda9f5f
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Zend/tests/closure_call_internal.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
Closure::call() on internal method
--FILE--
<?php

var_dump(Closure::fromCallable([new DateTime(), 'getTimestamp'])->call(new DateTime('@123')));

?>
--EXPECT--
int(123)
3 changes: 3 additions & 0 deletions Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ ZEND_METHOD(Closure, call)
my_function.common.fn_flags &= ~ZEND_ACC_CLOSURE;
/* use scope of passed object */
my_function.common.scope = Z_OBJCE_P(newthis);
if (closure->func.type == ZEND_INTERNAL_FUNCTION) {
my_function.internal_function.handler = closure->orig_internal_handler;
}
fci_cache.function_handler = &my_function;

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

0 comments on commit eda9f5f

Please sign in to comment.