Skip to content

Commit 084e409

Browse files
committed
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
1 parent 8b4ef3a commit 084e409

15 files changed

+32
-63
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ PHP NEWS
1010
. Added `clamp()`. (kylekatarnls, thinkverse)
1111
. Fix OSS-Fuzz #429429090 (Failed assertion on unset() with uninitialized
1212
container). (ilutov)
13+
. Fixed GH-20564 (Don't call autoloaders with pending exception). (ilutov)
1314

1415
- Date:
1516
. Update timelib to 2022.16. (Derick)

UPGRADING.INTERNALS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
5454
ZEND_ACC_USER_ARG_INFO flag was set.
5555
. Added zend_ast_call_get_args() to fetch the argument node from any call
5656
node.
57+
. The zend_exception_save() and zend_exception_restore() functions were
58+
removed.
5759

5860
========================
5961
2. Build system changes

Zend/tests/gh20564.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-20564: Don't call autoloaders with pending exception
3+
--CREDITS--
4+
Viet Hoang Luu (@vi3tL0u1s)
5+
--FILE--
6+
<?php
7+
8+
class A {
9+
function __call($method, $args) {
10+
eval("<<<ENDOFSTRING\n Test\n ENDOFSTRING;");
11+
spl_autoload_register('A::test');
12+
array_map('B::test', []);
13+
}
14+
}
15+
16+
try {
17+
(new A)->test();
18+
} catch (Throwable $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
22+
?>
23+
--EXPECT--
24+
array_map(): Argument #1 ($callback) must be a valid callback or null, class "B" not found

Zend/zend.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,6 @@ ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handl
19781978
zend_result ret = SUCCESS;
19791979
if (op_array) {
19801980
zend_execute(op_array, retval);
1981-
zend_exception_restore();
19821981
if (UNEXPECTED(EG(exception))) {
19831982
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
19841983
zend_user_exception_handler();

Zend/zend_exceptions.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -145,31 +145,6 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
145145
}
146146
/* }}} */
147147

148-
void zend_exception_save(void) /* {{{ */
149-
{
150-
if (EG(prev_exception)) {
151-
zend_exception_set_previous(EG(exception), EG(prev_exception));
152-
}
153-
if (EG(exception)) {
154-
EG(prev_exception) = EG(exception);
155-
}
156-
EG(exception) = NULL;
157-
}
158-
/* }}} */
159-
160-
void zend_exception_restore(void) /* {{{ */
161-
{
162-
if (EG(prev_exception)) {
163-
if (EG(exception)) {
164-
zend_exception_set_previous(EG(exception), EG(prev_exception));
165-
} else {
166-
EG(exception) = EG(prev_exception);
167-
}
168-
EG(prev_exception) = NULL;
169-
}
170-
}
171-
/* }}} */
172-
173148
static zend_always_inline bool is_handle_exception_set(void) {
174149
zend_execute_data *execute_data = EG(current_execute_data);
175150
return !execute_data
@@ -241,10 +216,6 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /*
241216
ZEND_API void zend_clear_exception(void) /* {{{ */
242217
{
243218
zend_object *exception;
244-
if (EG(prev_exception)) {
245-
OBJ_RELEASE(EG(prev_exception));
246-
EG(prev_exception) = NULL;
247-
}
248219
if (!EG(exception)) {
249220
return;
250221
}

Zend/zend_exceptions.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ extern ZEND_API zend_class_entry *zend_ce_unhandled_match_error;
4141
extern ZEND_API zend_class_entry *zend_ce_request_parse_body_exception;
4242

4343
ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous);
44-
ZEND_API void zend_exception_save(void);
45-
ZEND_API void zend_exception_restore(void);
4644

4745
ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception);
4846

Zend/zend_execute.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,7 @@ ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_exe
13151315

13161316
if ((fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) &&
13171317
!zend_verify_internal_arg_types(fbc, call)) {
1318+
zend_clear_exception();
13181319
return 1;
13191320
}
13201321

Zend/zend_execute_API.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ void init_executor(void) /* {{{ */
176176
ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false);
177177

178178
EG(exception) = NULL;
179-
EG(prev_exception) = NULL;
180179

181180
EG(fake_scope) = NULL;
182181
EG(trampoline).common.function_name = NULL;
@@ -1268,9 +1267,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
12681267
zend_long previous_lineno = EG(lineno_override);
12691268
EG(filename_override) = NULL;
12701269
EG(lineno_override) = -1;
1271-
zend_exception_save();
12721270
ce = zend_autoload(autoload_name, lc_name);
1273-
zend_exception_restore();
12741271
EG(filename_override) = previous_filename;
12751272
EG(lineno_override) = previous_lineno;
12761273

Zend/zend_globals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ struct _zend_executor_globals {
255255

256256
zend_objects_store objects_store;
257257
zend_lazy_objects_store lazy_objects_store;
258-
zend_object *exception, *prev_exception;
258+
zend_object *exception;
259259
const zend_op *opline_before_exception;
260260
zend_op exception_op[3];
261261

Zend/zend_language_scanner.l

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,7 +2765,8 @@ skip_escape_conversion:
27652765
27662766
zend_ptr_stack_reverse_apply(&current_state.heredoc_label_stack, copy_heredoc_label_stack);
27672767
2768-
zend_exception_save();
2768+
zend_object *prev_exception = EG(exception);
2769+
EG(exception) = NULL;
27692770
while (heredoc_nesting_level) {
27702771
zval zv;
27712772
int retval;
@@ -2794,7 +2795,7 @@ skip_escape_conversion:
27942795
heredoc_nesting_level = 0;
27952796
}
27962797
}
2797-
zend_exception_restore();
2798+
EG(exception) = prev_exception;
27982799
27992800
if (
28002801
(first_token == T_VARIABLE

0 commit comments

Comments
 (0)