From d65d3f5298dcc8d94bcac96e8bf2441dceb393ac Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 24 Jul 2020 10:16:38 +0200 Subject: Fix bug #79108 Don't expose references in debug_backtrace() or exception traces. This is regardless of whether the argument is by-reference or not. As a side-effect of this change, exception traces may now acquire the interior value of a reference, which may be unexpected for some internal functions. This is what necessitated the change in the spl_array sort implementation. --- Zend/zend_builtin_functions.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'Zend/zend_builtin_functions.c') diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c75f2f465b..1de771660a 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1591,16 +1591,12 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / * and we have to access them through symbol_table * See: https://bugs.php.net/bug.php?id=73156 */ - zend_string *arg_name; - zval *arg; - while (i < first_extra_arg) { - arg_name = call->func->op_array.vars[i]; - arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1); + zend_string *arg_name = call->func->op_array.vars[i]; + zval *arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1); if (arg) { - if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } + ZVAL_DEREF(arg); + Z_TRY_ADDREF_P(arg); ZEND_HASH_FILL_SET(arg); } else { ZEND_HASH_FILL_SET_NULL(); @@ -1611,10 +1607,10 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / } else { while (i < first_extra_arg) { if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) { - if (Z_OPT_REFCOUNTED_P(p)) { - Z_ADDREF_P(p); - } - ZEND_HASH_FILL_SET(p); + zval *arg = p; + ZVAL_DEREF(arg); + Z_TRY_ADDREF_P(arg); + ZEND_HASH_FILL_SET(arg); } else { ZEND_HASH_FILL_SET_NULL(); } @@ -1628,10 +1624,10 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / while (i < num_args) { if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) { - if (Z_OPT_REFCOUNTED_P(p)) { - Z_ADDREF_P(p); - } - ZEND_HASH_FILL_SET(p); + zval *arg = p; + ZVAL_DEREF(arg); + Z_TRY_ADDREF_P(arg); + ZEND_HASH_FILL_SET(arg); } else { ZEND_HASH_FILL_SET_NULL(); } -- cgit v1.2.1