File tree Expand file tree Collapse file tree 4 files changed +71
-3
lines changed Expand file tree Collapse file tree 4 files changed +71
-3
lines changed Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-20183: Stale EG(opline_before_exception) pointer through eval
3+ --CREDITS--
4+ Viet Hoang Luu (@vi3tL0u1s)
5+ --FILE--
6+ <?php
7+
8+ class A {
9+ function __destruct () {
10+ eval ('try { throw new Error(); } catch (Error $e) {} ' );
11+ debug_print_backtrace ();
12+ }
13+ }
14+
15+ B::$ b = new A ;
16+
17+ ?>
18+ --EXPECTF--
19+ #0 %s(10): A->__destruct()
20+
21+ Fatal error: Uncaught Error: Class "B" not found in %s:10
22+ Stack trace:
23+ #0 {main}
24+ thrown in %s on line 10
Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-20183: Stale EG(opline_before_exception) pointer through eval
3+ --CREDITS--
4+ Arnaud Le Blanc <
[email protected] >
5+ --FILE--
6+ <?php
7+
8+ function gen () {
9+ try {
10+ yield 1 ;
11+ } finally {
12+ eval ('try { throw new Error(); } catch (Error) {} ' );
13+ debug_print_backtrace ();
14+ }
15+ }
16+
17+ class A {
18+ private $ gen ;
19+ function __construct () {
20+ $ this ->gen = gen ();
21+ $ this ->gen ->rewind ();
22+ }
23+ }
24+
25+ B::$ a = new A ();
26+
27+ ?>
28+ --EXPECTF--
29+ #0 %s(20): gen()
30+
31+ Fatal error: Uncaught Error: Class "B" not found in %s:20
32+ Stack trace:
33+ #0 {main}
34+ thrown in %s on line 20
Original file line number Diff line number Diff line change @@ -308,9 +308,16 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
308308 ZEND_CALL_VAR (ex , ex -> func -> op_array .opcodes [try_catch -> finally_end ].op1 .var );
309309
310310 zend_generator_cleanup_unfinished_execution (generator , ex , try_catch -> finally_op );
311- zend_object * old_exception = EG (exception );
312- const zend_op * old_opline_before_exception = EG (opline_before_exception );
313- EG (exception ) = NULL ;
311+
312+ zend_object * old_exception = NULL ;
313+ const zend_op * old_opline_before_exception = NULL ;
314+ if (EG (exception )) {
315+ EG (current_execute_data )-> opline = EG (opline_before_exception );
316+ old_exception = EG (exception );
317+ old_opline_before_exception = EG (opline_before_exception );
318+ EG (exception ) = NULL ;
319+ }
320+
314321 Z_OBJ_P (fast_call ) = NULL ;
315322 Z_OPLINE_NUM_P (fast_call ) = (uint32_t )-1 ;
316323
@@ -320,6 +327,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
320327 zend_generator_resume (generator );
321328
322329 if (old_exception ) {
330+ EG (current_execute_data )-> opline = EG (exception_op );
323331 EG (opline_before_exception ) = old_opline_before_exception ;
324332 if (EG (exception )) {
325333 zend_exception_set_previous (EG (exception ), old_exception );
Original file line number Diff line number Diff line change @@ -161,6 +161,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
161161 && ZEND_USER_CODE (EG (current_execute_data )-> func -> common .type )) {
162162 zend_rethrow_exception (EG (current_execute_data ));
163163 }
164+ EG (current_execute_data )-> opline = EG (opline_before_exception );
164165 old_exception = EG (exception );
165166 old_opline_before_exception = EG (opline_before_exception );
166167 EG (exception ) = NULL ;
@@ -170,6 +171,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
170171 zend_call_known_instance_method_with_0_params (destructor , object , NULL );
171172
172173 if (old_exception ) {
174+ EG (current_execute_data )-> opline = EG (exception_op );
173175 EG (opline_before_exception ) = old_opline_before_exception ;
174176 if (EG (exception )) {
175177 zend_exception_set_previous (EG (exception ), old_exception );
You can’t perform that action at this time.
0 commit comments