Browse Source

Fixed bug #73156 (segfault on undefined function)

pull/2150/head
Dmitry Stogov 9 years ago
parent
commit
d279118422
  1. 1
      NEWS
  2. 50
      Zend/tests/bug73156.phpt
  3. 30
      Zend/zend_builtin_functions.c

1
NEWS

@ -11,6 +11,7 @@ PHP NEWS
password_verify). (Anatol)
. Fixed bug #73058 (crypt broken when salt is 'too' long). (Anatol)
. Fixed bug #69579 (Invalid free in extension trait). (John Boehr)
. 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

@ -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) {

Loading…
Cancel
Save