diff options
-rw-r--r-- | Zend/tests/undef_var_in_verify_return.phpt | 23 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 12 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 5 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 25 |
4 files changed, 56 insertions, 9 deletions
diff --git a/Zend/tests/undef_var_in_verify_return.phpt b/Zend/tests/undef_var_in_verify_return.phpt new file mode 100644 index 0000000000..b8c263c424 --- /dev/null +++ b/Zend/tests/undef_var_in_verify_return.phpt @@ -0,0 +1,23 @@ +--TEST-- +Throwing undef var in verify return +--FILE-- +<?php + +set_error_handler(function(int $severity, string $message, string $filename, int $lineNumber): void { + throw new ErrorException($message, 0, $severity, $filename, $lineNumber); +}); + +function test(): string { + return $test; +} + +test(); + +?> +--EXPECTF-- +Fatal error: Uncaught ErrorException: Undefined variable $test in %s:%d +Stack trace: +#0 %s(%d): {closure}(2, 'Undefined varia...', '%s', 8) +#1 %s(%d): test() +#2 {main} + thrown in %s on line %d diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index f037f0399a..b52b1ab113 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -144,6 +144,13 @@ void zend_exception_restore(void) /* {{{ */ } /* }}} */ +static zend_always_inline zend_bool is_handle_exception_set() { + zend_execute_data *execute_data = EG(current_execute_data); + return !execute_data->func + || !ZEND_USER_CODE(execute_data->func->common.type) + || execute_data->opline->opcode == ZEND_HANDLE_EXCEPTION; +} + ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* {{{ */ { #ifdef HAVE_DTRACE @@ -161,6 +168,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* zend_exception_set_previous(exception, EG(exception)); EG(exception) = exception; if (previous) { + ZEND_ASSERT(is_handle_exception_set() && "HANDLE_EXCEPTION not set?"); return; } } @@ -179,9 +187,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* zend_throw_exception_hook(exception); } - if (!EG(current_execute_data)->func || - !ZEND_USER_CODE(EG(current_execute_data)->func->common.type) || - EG(current_execute_data)->opline->opcode == ZEND_HANDLE_EXCEPTION) { + if (is_handle_exception_set()) { /* no need to rethrow the exception */ return; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d647dddeab..cff1012aca 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4195,8 +4195,11 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV if (OP1_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - 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 27d1ee1571..1786cfcc83 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -9707,8 +9707,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -20051,8 +20054,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -27656,8 +27662,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -34853,8 +34862,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } @@ -46545,8 +46557,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { SAVE_OPLINE(); retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } } |