summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-09-26 14:14:57 +0300
committerDmitry Stogov <dmitry@zend.com>2016-09-26 14:14:57 +0300
commitd2791184228ff86878acda46567a3bc2a94f2a36 (patch)
treeac181b827714dcbbcc4b56a141157f4caf6fd702 /Zend/zend_builtin_functions.c
parent4e7b5ca45953cb22213bbd9ed5b95b4b1898bab0 (diff)
downloadphp-git-d2791184228ff86878acda46567a3bc2a94f2a36.tar.gz
Fixed bug #73156 (segfault on undefined function)
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index c3160d0a6f..9aa6725af4 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -2211,9 +2211,33 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
zend_hash_real_init(Z_ARRVAL_P(arg_array), 1);
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(arg_array)) {
if (call->func->type == ZEND_USER_FUNCTION) {
- uint32_t first_extra_arg = call->func->op_array.num_args;
+ uint32_t first_extra_arg = MIN(num_args, call->func->op_array.num_args);
- if (ZEND_CALL_NUM_ARGS(call) > first_extra_arg) {
+ if (UNEXPECTED(call->symbol_table)) {
+ /* In case of attached symbol_table, values on stack may be invalid
+ * 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_ind(call->symbol_table, arg_name);
+ if (arg) {
+ if (Z_OPT_REFCOUNTED_P(arg)) {
+ Z_ADDREF_P(arg);
+ }
+ n++;
+ ZEND_HASH_FILL_ADD(arg);
+ } else {
+ zval tmp;
+ ZVAL_UNDEF(&tmp);
+ ZEND_HASH_FILL_ADD(&tmp);
+ }
+ i++;
+ }
+ } else {
while (i < first_extra_arg) {
if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
if (Z_OPT_REFCOUNTED_P(p)) {
@@ -2225,8 +2249,8 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
p++;
i++;
}
- p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T);
}
+ p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T);
}
while (i < num_args) {