Don’t reset func in zend_closure_internal_handler

The pointer is used in _zend_observe_fcall_begin().
This commit is contained in:
Florian Sowade 2022-10-24 21:37:54 +02:00 committed by Bob Weinand
parent 605136204e
commit 8dabbda8bc
3 changed files with 28 additions and 1 deletions

View file

@ -696,7 +696,6 @@ static ZEND_NAMED_FUNCTION(zend_closure_internal_handler) /* {{{ */
zend_closure *closure = (zend_closure*)ZEND_CLOSURE_OBJECT(EX(func));
closure->orig_internal_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
OBJ_RELEASE((zend_object*)closure);
EX(func) = NULL;
}
/* }}} */

View file

@ -208,6 +208,7 @@ ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_obs
static inline zend_execute_data **prev_observed_frame(zend_execute_data *execute_data) {
zend_function *func = EX(func);
ZEND_ASSERT(func);
return (zend_execute_data **)&Z_PTR_P(EX_VAR_NUM((ZEND_USER_CODE(func->type) ? func->op_array.last_var : ZEND_CALL_NUM_ARGS(execute_data)) + func->common.T - 1));
}
@ -260,6 +261,7 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute
static inline void call_end_observers(zend_execute_data *execute_data, zval *return_value) {
zend_function *func = execute_data->func;
ZEND_ASSERT(func);
zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)&ZEND_OBSERVER_DATA(func) + zend_observers_fcall_list.count;
// TODO: Fix exceptions from generators

View file

@ -0,0 +1,26 @@
--TEST--
Observer: Observability of closures of builtin functions
--EXTENSIONS--
zend_test
--INI--
zend_test.observer.enabled=1
zend_test.observer.observe_all=1
--FILE--
<?php
$closure = strlen(...);
var_dump($closure('test'));
echo 'DONE' . PHP_EOL;
?>
--EXPECTF--
<!-- init '%s' -->
<file '%s'>
<!-- init strlen() -->
<strlen>
</strlen>
<!-- init var_dump() -->
<var_dump>
int(4)
</var_dump>
DONE
</file '%s'>