File tree 5 files changed +93
-1
lines changed
5 files changed +93
-1
lines changed Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ PHP NEWS
10
10
array is contained in the second). (ilutov)
11
11
. Fixed bug GH-10737 (PHP 8.1.16 segfaults on line 597 of
12
12
sapi/apache2handler/sapi_apache2.c). (nielsdos, ElliotNB)
13
+ . Fixed bug GH-11028 (Heap Buffer Overflow in zval_undefined_cv.). (nielsdos)
13
14
14
15
- DOM:
15
16
. Fixed bug #80602 (Segfault when using DOMChildNode::before()).
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GH-11028 (Heap Buffer Overflow in zval_undefined_cv with generators) - other types variant
3
+ --FILE--
4
+ <?php
5
+ function generator ($ x ) {
6
+ try {
7
+ yield $ x => 0 ;
8
+ } finally {
9
+ return [];
10
+ }
11
+ }
12
+
13
+ function test ($ msg , $ x ) {
14
+ echo "yield $ msg \n" ;
15
+ try {
16
+ var_dump ([...generator ($ x )]);
17
+ } catch (Throwable $ e ) {
18
+ echo $ e ->getMessage (), "\n" ;
19
+ }
20
+ }
21
+
22
+ test ("null " , null );
23
+ test ("false " , false );
24
+ test ("true " , true );
25
+ test ("object " , new stdClass );
26
+ ?>
27
+ --EXPECT--
28
+ yield null
29
+ Keys must be of type int|string during array unpacking
30
+ yield false
31
+ Keys must be of type int|string during array unpacking
32
+ yield true
33
+ Keys must be of type int|string during array unpacking
34
+ yield object
35
+ Keys must be of type int|string during array unpacking
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GH-11028 (Heap Buffer Overflow in zval_undefined_cv with generators) - original variant
3
+ --FILE--
4
+ <?php
5
+ $ c = (function () {
6
+ [
7
+ ...($ r = (function () {
8
+ try {
9
+ yield $ a => 0 ;
10
+ } finally {
11
+ return [];
12
+ }
13
+ })()),
14
+ ];
15
+ })()[0 ];
16
+ ?>
17
+ --EXPECTF--
18
+ Warning: Undefined variable $a in %s on line %d
19
+
20
+ Fatal error: Uncaught Error: Keys must be of type int|string during array unpacking in %s:%d
21
+ Stack trace:
22
+ #0 %s(%d): {closure}()
23
+ #1 {main}
24
+ thrown in %s on line %d
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GH-11028 (Heap Buffer Overflow in zval_undefined_cv with generators) - throw in finally variant
3
+ --FILE--
4
+ <?php
5
+ function generator () {
6
+ try {
7
+ yield null => 0 ;
8
+ } finally {
9
+ throw new Exception ("exception " );
10
+ return [];
11
+ }
12
+ }
13
+
14
+ try {
15
+ var_dump ([...generator ()]);
16
+ } catch (Throwable $ e ) {
17
+ echo $ e ->getMessage (), "\n" ;
18
+ }
19
+ ?>
20
+ --EXPECT--
21
+ exception
Original file line number Diff line number Diff line change @@ -279,14 +279,25 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
279
279
ZEND_CALL_VAR (ex , ex -> func -> op_array .opcodes [try_catch -> finally_end ].op1 .var );
280
280
281
281
zend_generator_cleanup_unfinished_execution (generator , ex , try_catch -> finally_op );
282
- Z_OBJ_P (fast_call ) = EG (exception );
282
+ zend_object * old_exception = EG (exception );
283
+ const zend_op * old_opline_before_exception = EG (opline_before_exception );
283
284
EG (exception ) = NULL ;
285
+ Z_OBJ_P (fast_call ) = NULL ;
284
286
Z_OPLINE_NUM_P (fast_call ) = (uint32_t )-1 ;
285
287
286
288
ex -> opline = & ex -> func -> op_array .opcodes [try_catch -> finally_op ];
287
289
generator -> flags |= ZEND_GENERATOR_FORCED_CLOSE ;
288
290
zend_generator_resume (generator );
289
291
292
+ if (old_exception ) {
293
+ EG (opline_before_exception ) = old_opline_before_exception ;
294
+ if (EG (exception )) {
295
+ zend_exception_set_previous (EG (exception ), old_exception );
296
+ } else {
297
+ EG (exception ) = old_exception ;
298
+ }
299
+ }
300
+
290
301
/* TODO: If we hit another yield inside try/finally,
291
302
* should we also jump to the next finally block? */
292
303
break ;
You can’t perform that action at this time.
0 commit comments