diff --git a/NEWS b/NEWS index 14c77d022e3..e79cffed237 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed bug #60833 (self, parent, static behave inconsistently case-sensitive). (Stas, mario at include-once dot org) . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik). + . Fixed bug #63830 (Segfault on undefined function call in nested generator). + (Nikita Popov) - CLI server: . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi) diff --git a/Zend/tests/generators/nested_calls_with_die.phpt b/Zend/tests/generators/nested_calls_with_die.phpt new file mode 100644 index 00000000000..f43d89ba219 --- /dev/null +++ b/Zend/tests/generators/nested_calls_with_die.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test nested calls with die() in a generator +--FILE-- +rewind(); +} + +function function_with_4_args() { + function_with_3_args(4, 5, 6); +} + +function outerGen() { + function_with_4_args(0, 1, 2, 3); + yield; // force generator +} + +$outerGen = outerGen(); +$outerGen->rewind(); + +?> +--EXPECT-- +Test diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 621320614ca..c1dbee124f3 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -94,10 +94,16 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished /* Clear any backed up stack arguments */ if (generator->stack != EG(argument_stack)) { - void **stack_frame = zend_vm_stack_frame_base(execute_data); - while (generator->stack->top != stack_frame) { - zval_ptr_dtor((zval**)stack_frame); - stack_frame++; + void **ptr = generator->stack->top - 1; + void **end = zend_vm_stack_frame_base(execute_data); + + /* If the top stack element is the argument count, skip it */ + if (execute_data->function_state.arguments) { + ptr--; + } + + for (; ptr >= end; --ptr) { + zval_ptr_dtor((zval**) ptr); } }