diff options
-rw-r--r-- | Zend/tests/methods-on-non-objects-args-catch.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/methods-on-non-objects-catch.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/methods-on-non-objects.phpt | 12 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 21 |
4 files changed, 68 insertions, 1 deletions
diff --git a/Zend/tests/methods-on-non-objects-args-catch.phpt b/Zend/tests/methods-on-non-objects-args-catch.phpt new file mode 100644 index 0000000000..2dd54cb65d --- /dev/null +++ b/Zend/tests/methods-on-non-objects-args-catch.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump($x->method(1, 2, 3)); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on a non-object" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-catch.phpt b/Zend/tests/methods-on-non-objects-catch.phpt new file mode 100644 index 0000000000..30a9c774cc --- /dev/null +++ b/Zend/tests/methods-on-non-objects-catch.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump($x->method()); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on a non-object" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects.phpt b/Zend/tests/methods-on-non-objects.phpt new file mode 100644 index 0000000000..cc426374c8 --- /dev/null +++ b/Zend/tests/methods-on-non-objects.phpt @@ -0,0 +1,12 @@ +--TEST-- +Method calls on non-objects raise recoverable errors +--FILE-- +<?php + +$x= null; +$x->method(); +echo "Should not get here!\n"; +?> +--EXPECTF-- + +Catchable fatal error: Call to a member function method() on a non-object in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 195772a395..10a71a69df 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2463,7 +2463,26 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) FREE_OP2(); HANDLE_EXCEPTION(); } - zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + + zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + FREE_OP2(); + FREE_OP1_IF_VAR(); + CHECK_EXCEPTION(); + + /* Skip over arguments until fcall opcode, return NULL */ + do { + ZEND_VM_INC_OPCODE(); + opline++; + } while (ZEND_DO_FCALL_BY_NAME != opline->opcode); + + MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr); + ZVAL_NULL(EX_T(opline->result.var).var.ptr); + Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr); + Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1); + EX_T(opline->result.var).var.fcall_returned_reference = 0; + EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; + ZEND_VM_NEXT_OPCODE(); + return; } if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { |