1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 08:12:21 +01:00

Remove zend_exception_save() and zend_exception_restore()

These are leftovers from the pre-PHP-7.0 era. This also implicitly solves
GH-20564 by not clearing exceptions before entering the autoloader.

Closes GH-20256
Fixes GH-20564
This commit is contained in:
Ilija Tovilo
2025-10-22 01:03:43 +02:00
parent 8b4ef3a09f
commit 084e409694
15 changed files with 32 additions and 63 deletions

1
NEWS
View File

@@ -10,6 +10,7 @@ PHP NEWS
. Added `clamp()`. (kylekatarnls, thinkverse)
. Fix OSS-Fuzz #429429090 (Failed assertion on unset() with uninitialized
container). (ilutov)
. Fixed GH-20564 (Don't call autoloaders with pending exception). (ilutov)
- Date:
. Update timelib to 2022.16. (Derick)

View File

@@ -54,6 +54,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
ZEND_ACC_USER_ARG_INFO flag was set.
. Added zend_ast_call_get_args() to fetch the argument node from any call
node.
. The zend_exception_save() and zend_exception_restore() functions were
removed.
========================
2. Build system changes

24
Zend/tests/gh20564.phpt Normal file
View File

@@ -0,0 +1,24 @@
--TEST--
GH-20564: Don't call autoloaders with pending exception
--CREDITS--
Viet Hoang Luu (@vi3tL0u1s)
--FILE--
<?php
class A {
function __call($method, $args) {
eval("<<<ENDOFSTRING\n Test\n ENDOFSTRING;");
spl_autoload_register('A::test');
array_map('B::test', []);
}
}
try {
(new A)->test();
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
array_map(): Argument #1 ($callback) must be a valid callback or null, class "B" not found

View File

@@ -1978,7 +1978,6 @@ ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handl
zend_result ret = SUCCESS;
if (op_array) {
zend_execute(op_array, retval);
zend_exception_restore();
if (UNEXPECTED(EG(exception))) {
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
zend_user_exception_handler();

View File

@@ -145,31 +145,6 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
}
/* }}} */
void zend_exception_save(void) /* {{{ */
{
if (EG(prev_exception)) {
zend_exception_set_previous(EG(exception), EG(prev_exception));
}
if (EG(exception)) {
EG(prev_exception) = EG(exception);
}
EG(exception) = NULL;
}
/* }}} */
void zend_exception_restore(void) /* {{{ */
{
if (EG(prev_exception)) {
if (EG(exception)) {
zend_exception_set_previous(EG(exception), EG(prev_exception));
} else {
EG(exception) = EG(prev_exception);
}
EG(prev_exception) = NULL;
}
}
/* }}} */
static zend_always_inline bool is_handle_exception_set(void) {
zend_execute_data *execute_data = EG(current_execute_data);
return !execute_data
@@ -241,10 +216,6 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /*
ZEND_API void zend_clear_exception(void) /* {{{ */
{
zend_object *exception;
if (EG(prev_exception)) {
OBJ_RELEASE(EG(prev_exception));
EG(prev_exception) = NULL;
}
if (!EG(exception)) {
return;
}

View File

@@ -41,8 +41,6 @@ extern ZEND_API zend_class_entry *zend_ce_unhandled_match_error;
extern ZEND_API zend_class_entry *zend_ce_request_parse_body_exception;
ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous);
ZEND_API void zend_exception_save(void);
ZEND_API void zend_exception_restore(void);
ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception);

View File

@@ -1315,6 +1315,7 @@ ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_exe
if ((fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) &&
!zend_verify_internal_arg_types(fbc, call)) {
zend_clear_exception();
return 1;
}

View File

@@ -176,7 +176,6 @@ void init_executor(void) /* {{{ */
ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false);
EG(exception) = NULL;
EG(prev_exception) = NULL;
EG(fake_scope) = NULL;
EG(trampoline).common.function_name = NULL;
@@ -1268,9 +1267,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
zend_long previous_lineno = EG(lineno_override);
EG(filename_override) = NULL;
EG(lineno_override) = -1;
zend_exception_save();
ce = zend_autoload(autoload_name, lc_name);
zend_exception_restore();
EG(filename_override) = previous_filename;
EG(lineno_override) = previous_lineno;

View File

@@ -255,7 +255,7 @@ struct _zend_executor_globals {
zend_objects_store objects_store;
zend_lazy_objects_store lazy_objects_store;
zend_object *exception, *prev_exception;
zend_object *exception;
const zend_op *opline_before_exception;
zend_op exception_op[3];

View File

@@ -2765,7 +2765,8 @@ skip_escape_conversion:
zend_ptr_stack_reverse_apply(&current_state.heredoc_label_stack, copy_heredoc_label_stack);
zend_exception_save();
zend_object *prev_exception = EG(exception);
EG(exception) = NULL;
while (heredoc_nesting_level) {
zval zv;
int retval;
@@ -2794,7 +2795,7 @@ skip_escape_conversion:
heredoc_nesting_level = 0;
}
}
zend_exception_restore();
EG(exception) = prev_exception;
if (
(first_token == T_VARIABLE

View File

@@ -4797,10 +4797,8 @@ ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMPVAR|CV, ANY)
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
FREE_OP1();
HANDLE_EXCEPTION();
}
@@ -4813,7 +4811,6 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
SAVE_OPLINE();
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore();
if (EG(exception) == NULL) {
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}

14
Zend/zend_vm_execute.h generated
View File

@@ -5125,10 +5125,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
HANDLE_EXCEPTION();
@@ -5142,7 +5140,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CATCH_SPEC_CO
SAVE_OPLINE();
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore();
if (EG(exception) == NULL) {
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
@@ -15720,10 +15717,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_TM
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}
@@ -41901,10 +41896,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_CV
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
HANDLE_EXCEPTION();
@@ -60784,10 +60777,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
HANDLE_EXCEPTION();
@@ -60801,7 +60792,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CATCH_SPEC_CONST_T
SAVE_OPLINE();
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore();
if (EG(exception) == NULL) {
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
@@ -71277,10 +71267,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_TMPVAR_
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}
@@ -97358,10 +97346,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_CV_TAIL
}
} while (0);
zend_exception_save();
Z_TRY_ADDREF_P(value);
zend_throw_exception_object(value);
zend_exception_restore();
HANDLE_EXCEPTION();

View File

@@ -4663,7 +4663,6 @@ static zend_result accel_preload(const char *config, bool in_child)
zend_destroy_file_handle(&file_handle);
if (op_array) {
zend_execute(op_array, NULL);
zend_exception_restore();
if (UNEXPECTED(EG(exception))) {
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
zend_user_exception_handler();

View File

@@ -134,7 +134,6 @@ ZEND_ATTRIBUTE_UNUSED static void create_file(void) {
ZEND_ATTRIBUTE_UNUSED static void opcache_invalidate(void) {
steps_left = MAX_STEPS;
zend_exception_save();
zval retval, args[2];
zend_function *fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("opcache_invalidate"));
ZEND_ASSERT(fn != NULL);
@@ -145,5 +144,4 @@ ZEND_ATTRIBUTE_UNUSED static void opcache_invalidate(void) {
ZEND_ASSERT(Z_TYPE(retval) == IS_TRUE);
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&retval);
zend_exception_restore();
}

View File

@@ -716,10 +716,6 @@ static inline void phpdbg_handle_exception(void) /* {{{ */
phpdbg_writeln("%s", ZSTR_VAL(msg));
zend_string_release(msg);
if (EG(prev_exception)) {
OBJ_RELEASE(EG(prev_exception));
EG(prev_exception) = 0;
}
OBJ_RELEASE(ex);
EG(opline_before_exception) = NULL;
@@ -876,7 +872,6 @@ free_cmd:
} zend_end_try();
if (restore) {
zend_exception_restore();
zend_try {
zend_try_exception_handler();
PHPDBG_G(in_execution) = 1;