From 2c3b56ded0edc5a8dcb6322de2868dd094d4edf6 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:57:18 +0100 Subject: [PATCH] Fix GH-17216: Trampoline crash on error The error handling is incomplete on argument cleanup. 1. The fci is not cleared which means that zend_free_trampoline() is never called. 2. The cleaning for extra named arguments was missing, resulting in memory leak. Closes GH-17219. --- NEWS | 1 + Zend/tests/named_params/gh17216.phpt | 22 ++++++++++++++++++++++ Zend/zend_execute_API.c | 4 ++++ 3 files changed, 27 insertions(+) create mode 100644 Zend/tests/named_params/gh17216.phpt diff --git a/NEWS b/NEWS index c03d6879330d0..af04513c71846 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ PHP NEWS promotion correctly). (nielsdos) . Fixed bug GH-17211 (observer segfault on function loaded with dl()). (Arnaud) + . Fixed bug GH-17216 (Trampoline crash on error). (nielsdos) - Date: . Fixed bug GH-14709 DatePeriod::__construct() overflow on recurrences. diff --git a/Zend/tests/named_params/gh17216.phpt b/Zend/tests/named_params/gh17216.phpt new file mode 100644 index 0000000000000..4cb4df0ec431e --- /dev/null +++ b/Zend/tests/named_params/gh17216.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-17216 (Trampoline crash on error) +--FILE-- + "b", 1]; +try { + forward_static_call_array($callback, $array); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +echo "Done\n"; +?> +--EXPECT-- +Cannot use positional argument after named argument +Done diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e9b6009af05ae..fe37b024934df 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -842,7 +842,11 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ ZEND_CALL_NUM_ARGS(call) = i; cleanup_args: zend_vm_stack_free_args(call); + if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); + } zend_vm_stack_free_call_frame(call); + zend_release_fcall_info_cache(fci_cache); return SUCCESS; } }