File tree Expand file tree Collapse file tree 5 files changed +73
-3
lines changed Expand file tree Collapse file tree 5 files changed +73
-3
lines changed Original file line number Diff line number Diff line change 44
55- Core: 
66  . Fixed bug GH-20270 (Broken parent hook call with named arguments). (ilutov)
7+   . Fixed bug GH-20183 (Stale EG(opline_before_exception) pointer through eval).
8+     (ilutov)
79
810- Reflection:
911  . Fixed bug GH-20217 (ReflectionClass::isIterable() incorrectly returns true
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::$ bnew  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::$ anew  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 @@ -309,9 +309,16 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
309309				ZEND_CALL_VAR (ex , ex -> func -> op_array .opcodes [try_catch -> finally_end ].op1 .var );
310310
311311			zend_generator_cleanup_unfinished_execution (generator , ex , try_catch -> finally_op );
312- 			zend_object  * old_exception  =  EG (exception );
313- 			const  zend_op  * old_opline_before_exception  =  EG (opline_before_exception );
314- 			EG (exception ) =  NULL ;
312+ 
313+ 			zend_object  * old_exception  =  NULL ;
314+ 			const  zend_op  * old_opline_before_exception  =  NULL ;
315+ 			if  (EG (exception )) {
316+ 				EG (current_execute_data )-> opline  =  EG (opline_before_exception );
317+ 				old_exception  =  EG (exception );
318+ 				old_opline_before_exception  =  EG (opline_before_exception );
319+ 				EG (exception ) =  NULL ;
320+ 			}
321+ 
315322			Z_OBJ_P (fast_call ) =  NULL ;
316323			Z_OPLINE_NUM_P (fast_call ) =  (uint32_t )-1 ;
317324
@@ -321,6 +328,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
321328			zend_generator_resume (generator );
322329
323330			if  (old_exception ) {
331+ 				EG (current_execute_data )-> opline  =  EG (exception_op );
324332				EG (opline_before_exception ) =  old_opline_before_exception ;
325333				if  (EG (exception )) {
326334					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