Browse Source

Merge branch 'PHP-7.0' into PHP-7.1

* PHP-7.0:
  Fixed bug #73156 (segfault on undefined function)
pull/2137/head
Dmitry Stogov 9 years ago
parent
commit
bca7f02933
  1. 1
      NEWS
  2. 50
      Zend/tests/bug73156.phpt
  3. 30
      Zend/zend_builtin_functions.c

1
NEWS

@ -3,6 +3,7 @@ PHP NEWS
?? ??? 2016, PHP 7.1.0RC3
- Core:
. Fixed bug #73156 (segfault on undefined function). (Dmitry)
. Fixed bug #73163 (PHP hangs if error handler throws while accessing undef
const in default value). (Nikita)

50
Zend/tests/bug73156.phpt

@ -0,0 +1,50 @@
--TEST--
iBug #73156 (segfault on undefined function)
--FILE--
<?php
class A {
public function __call($name, $args) {
eval('$args = array(); var_dump(debug_backtrace());');
}
}
$a = new A();
$a->test("test");
?>
--EXPECTF--
array(2) {
[0]=>
array(3) {
["file"]=>
string(%d) "%sbug73156.php"
["line"]=>
int(4)
["function"]=>
string(4) "eval"
}
[1]=>
array(7) {
["file"]=>
string(%d) "%sbug73156.php"
["line"]=>
int(10)
["function"]=>
string(6) "__call"
["class"]=>
string(1) "A"
["object"]=>
object(A)#%d (0) {
}
["type"]=>
string(2) "->"
["args"]=>
array(2) {
[0]=>
string(4) "test"
[1]=>
array(0) {
}
}
}
}

30
Zend/zend_builtin_functions.c

@ -2293,9 +2293,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)) {
@ -2307,8 +2331,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) {

Loading…
Cancel
Save