diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2016-10-18 14:13:20 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2016-10-18 14:14:24 +0200 |
commit | 8b177f6a2a2782107461d7153385857872e2f4b9 (patch) | |
tree | 4bce69528a6b68e42ae43702b2d3d48152073405 | |
parent | 7bd4e7208e26e3e441717c0f33a154a385764d06 (diff) | |
download | php-git-8b177f6a2a2782107461d7153385857872e2f4b9.tar.gz |
Fixed bug #73338 (Exception thrown from error handler may crash)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug73338.phpt | 18 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 70 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 286 |
4 files changed, 271 insertions, 105 deletions
@@ -12,6 +12,8 @@ PHP NEWS . Fixed bug #73215 (uniqid() should use better random source). (Yasuo) . Fixed bug #73337 (try/catch not working with two exceptions inside a same operation). (Dmitry) + . Fixed bug #73338 (Exception thrown from error handler causes valgrind + warnings (and crashes)). (Bob, Dmitry) - GD: . Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb) diff --git a/Zend/tests/bug73338.phpt b/Zend/tests/bug73338.phpt new file mode 100644 index 0000000000..df4c3b66e4 --- /dev/null +++ b/Zend/tests/bug73338.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #73338: Ensure exceptions in function init opcodes are cleaned properly +--FILE-- +<?php + +try { call_user_func(new class { function __destruct () { throw new Error; } }); } catch (Error $e) {} + +set_error_handler(function() { throw new Error; }); + +try { var_dump(new stdClass, call_user_func("fail")); } catch (Error $e) {} + +try { (function() { call_user_func("fail"); })(); } catch (Error $e) {} + +try { [new class { static function foo() {} function __destruct () { throw new Error; } }, "foo"](); } catch (Error $e) {} + +?> +--EXPECTF-- +Warning: call_user_func() expects parameter 1 to be a valid callback, no array or string given in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index dcd460ad5d..6693ef316f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3012,15 +3012,19 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR GC_REFCOUNT(obj)++; /* For $this pointer */ } + FREE_OP2(); + FREE_OP1(); + + if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - FREE_OP2(); - FREE_OP1(); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSED|CV) @@ -3161,7 +3165,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) @@ -3283,7 +3287,6 @@ ZEND_VM_C_LABEL(try_function_name): called_scope = NULL; object = NULL; } - FREE_OP2(); } else if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && @@ -3297,7 +3300,6 @@ ZEND_VM_C_LABEL(try_function_name): call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - FREE_OP2(); } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; @@ -3381,7 +3383,6 @@ ZEND_VM_C_LABEL(try_function_name): GC_REFCOUNT(object)++; /* For $this pointer */ } } - FREE_OP2(); } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { function_name = Z_REFVAL_P(function_name); ZEND_VM_C_GOTO(try_function_name); @@ -3396,6 +3397,18 @@ ZEND_VM_C_LABEL(try_function_name): FREE_OP2(); HANDLE_EXCEPTION(); } + + FREE_OP2(); + if ((OP2_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release(fbc->common.function_name); + zend_free_trampoline(fbc); + } + HANDLE_EXCEPTION(); + } call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); @@ -3421,6 +3434,19 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; + called_scope = fcc.called_scope; + object = fcc.object; + if (error) { + efree(error); + /* This is the only soft error is_callable() can generate */ + zend_error(E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + FREE_OP2(); + HANDLE_EXCEPTION(); + } + } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ if (OP2_TYPE & (IS_VAR|IS_CV)) { @@ -3430,25 +3456,28 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; } - called_scope = fcc.called_scope; - object = fcc.object; if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - if (error) { - efree(error); - /* This is the only soft error is_callable() can generate */ - zend_error(E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + + FREE_OP2(); + if ((OP2_TYPE & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release((zend_object*)func->common.prototype); + } + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); } + HANDLE_EXCEPTION(); } } else { zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); efree(error); + FREE_OP2(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } func = (zend_function*)&zend_pass_function; called_scope = NULL; object = NULL; @@ -3459,8 +3488,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) call->prev_execute_data = EX(call); EX(call) = call; - FREE_OP2(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) @@ -4946,7 +4974,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4bc72bd24f..2c90e0073e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1995,7 +1995,6 @@ try_function_name: called_scope = NULL; object = NULL; } - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && @@ -2009,7 +2008,6 @@ try_function_name: call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; @@ -2093,7 +2091,6 @@ try_function_name: GC_REFCOUNT(object)++; /* For $this pointer */ } } - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { function_name = Z_REFVAL_P(function_name); goto try_function_name; @@ -2108,6 +2105,17 @@ try_function_name: HANDLE_EXCEPTION(); } + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release(fbc->common.function_name); + zend_free_trampoline(fbc); + } + HANDLE_EXCEPTION(); + } call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); @@ -2418,7 +2426,6 @@ try_function_name: called_scope = NULL; object = NULL; } - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && @@ -2432,7 +2439,6 @@ try_function_name: call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; @@ -2516,7 +2522,6 @@ try_function_name: GC_REFCOUNT(object)++; /* For $this pointer */ } } - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { function_name = Z_REFVAL_P(function_name); goto try_function_name; @@ -2531,6 +2536,17 @@ try_function_name: HANDLE_EXCEPTION(); } + + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release(fbc->common.function_name); + zend_free_trampoline(fbc); + } + HANDLE_EXCEPTION(); + } call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); @@ -2674,7 +2690,6 @@ try_function_name: called_scope = NULL; object = NULL; } - zval_ptr_dtor_nogc(free_op2); } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && @@ -2688,7 +2703,6 @@ try_function_name: call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - zval_ptr_dtor_nogc(free_op2); } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; @@ -2772,7 +2786,6 @@ try_function_name: GC_REFCOUNT(object)++; /* For $this pointer */ } } - zval_ptr_dtor_nogc(free_op2); } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { function_name = Z_REFVAL_P(function_name); goto try_function_name; @@ -2787,6 +2800,18 @@ try_function_name: zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } + + zval_ptr_dtor_nogc(free_op2); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release(fbc->common.function_name); + zend_free_trampoline(fbc); + } + HANDLE_EXCEPTION(); + } call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); @@ -3367,7 +3392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -5594,13 +5619,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -5741,7 +5770,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -5761,6 +5790,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS function_name = EX_CONSTANT(opline->op2); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; + called_scope = fcc.called_scope; + object = fcc.object; + if (error) { + efree(error); + /* This is the only soft error is_callable() can generate */ + zend_error(E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ if (IS_CONST & (IS_VAR|IS_CV)) { @@ -5770,25 +5812,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; } - called_scope = fcc.called_scope; - object = fcc.object; if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - if (error) { - efree(error); - /* This is the only soft error is_callable() can generate */ - zend_error(E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + + if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release((zend_object*)func->common.prototype); } + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + HANDLE_EXCEPTION(); } } else { zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); efree(error); + + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } func = (zend_function*)&zend_pass_function; called_scope = NULL; object = NULL; @@ -5799,7 +5843,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -7740,7 +7784,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9346,13 +9390,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9493,7 +9541,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9513,6 +9561,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; + called_scope = fcc.called_scope; + object = fcc.object; + if (error) { + efree(error); + /* This is the only soft error is_callable() can generate */ + zend_error(E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ if (IS_CV & (IS_VAR|IS_CV)) { @@ -9522,25 +9583,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; } - called_scope = fcc.called_scope; - object = fcc.object; if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - if (error) { - efree(error); - /* This is the only soft error is_callable() can generate */ - zend_error(E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + + if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release((zend_object*)func->common.prototype); + } + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); } + HANDLE_EXCEPTION(); } } else { zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); efree(error); + + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } func = (zend_function*)&zend_pass_function; called_scope = NULL; object = NULL; @@ -9551,7 +9614,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -11176,14 +11239,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -11324,7 +11391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -11344,6 +11411,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; + called_scope = fcc.called_scope; + object = fcc.object; + if (error) { + efree(error); + /* This is the only soft error is_callable() can generate */ + zend_error(E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) { @@ -11353,25 +11433,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; } - called_scope = fcc.called_scope; - object = fcc.object; if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ } - if (error) { - efree(error); - /* This is the only soft error is_callable() can generate */ - zend_error(E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + + zval_ptr_dtor_nogc(free_op2); + if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release((zend_object*)func->common.prototype); } + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + HANDLE_EXCEPTION(); } } else { zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); efree(error); + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } func = (zend_function*)&zend_pass_function; called_scope = NULL; object = NULL; @@ -11382,8 +11465,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -15482,7 +15564,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -17726,7 +17808,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19365,7 +19447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -21010,7 +21092,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -22602,7 +22684,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -23985,13 +24067,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -26412,13 +26498,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -27916,14 +28006,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -32200,13 +32294,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -37304,13 +37402,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA GC_REFCOUNT(obj)++; /* For $this pointer */ } + + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -39899,14 +40001,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); + + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -42141,14 +42247,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op1); + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -44289,14 +44399,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op1); + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -45435,15 +45549,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T GC_REFCOUNT(obj)++; /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, obj); call->prev_execute_data = EX(call); EX(call) = call; - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) |