From 1b88afe1c395135f11dec63e8c2666f793c1e7b7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 21 Oct 2024 14:59:36 +0200 Subject: [PATCH] Fix propagation of ACC_RETURN_REFERENCE flag for call trampoline Fixes GH-16515 --- Zend/tests/gh16515.phpt | 16 ++++++++++++++++ Zend/zend_closures.c | 2 +- Zend/zend_object_handlers.c | 5 ++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/gh16515.phpt diff --git a/Zend/tests/gh16515.phpt b/Zend/tests/gh16515.phpt new file mode 100644 index 0000000000000..63bb447e7ba2e --- /dev/null +++ b/Zend/tests/gh16515.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-16515: Incorrect propagation of ZEND_ACC_RETURN_REFERENCE for call trampoline +--FILE-- +bar(...)); + +?> +--EXPECTF-- +Notice: Only variable references should be returned by reference in %s on line %d diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index bbd3b85e6fba0..f261edb22bc90 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -845,7 +845,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* { memset(&trampoline, 0, sizeof(zend_internal_function)); trampoline.type = ZEND_INTERNAL_FUNCTION; - trampoline.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC; + trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC|ZEND_ACC_RETURN_REFERENCE); trampoline.handler = zend_closure_call_magic; trampoline.function_name = mptr->common.function_name; trampoline.scope = mptr->common.scope; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index def9695ed98bd..3446fb2c96434 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1281,7 +1281,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend func->arg_flags[0] = 0; func->arg_flags[1] = 0; func->arg_flags[2] = 0; - func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_PUBLIC | ZEND_ACC_VARIADIC; + func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE + | ZEND_ACC_PUBLIC + | ZEND_ACC_VARIADIC + | (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE); if (is_static) { func->fn_flags |= ZEND_ACC_STATIC; }