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 @@ -12,6 +12,8 @@ PHP                                                                        NEWS
1212  . Fixed bug GH-20177 (Accessing overridden private property in
1313    get_object_vars() triggers assertion error). (ilutov)
1414  . Fixed bug GH-20270 (Broken parent hook call with named arguments). (ilutov)
15+   . Fixed bug GH-20183 (Stale EG(opline_before_exception) pointer through eval).
16+     (ilutov)
1517
1618- DOM:
1719  . Partially fixed bug GH-16317 (DOM classes do not allow
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 @@ -185,6 +185,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
185185				 &&  ZEND_USER_CODE (EG (current_execute_data )-> func -> common .type )) {
186186					zend_rethrow_exception (EG (current_execute_data ));
187187				}
188+ 				EG (current_execute_data )-> opline  =  EG (opline_before_exception );
188189				old_exception  =  EG (exception );
189190				old_opline_before_exception  =  EG (opline_before_exception );
190191				EG (exception ) =  NULL ;
@@ -194,6 +195,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
194195		zend_call_known_instance_method_with_0_params (destructor , object , NULL );
195196
196197		if  (old_exception ) {
198+ 			EG (current_execute_data )-> opline  =  EG (exception_op );
197199			EG (opline_before_exception ) =  old_opline_before_exception ;
198200			if  (EG (exception )) {
199201				zend_exception_set_previous (EG (exception ), old_exception );
 
 
   
 
     
   
   
          
    
    
     
    
      
     
     
    You can’t perform that action at this time.
  
 
    
  
    
      
        
     
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments