Fix bug #63830: Segfault on undefined function call in nested generator

This also reverses the destruction order of the pushed arguments to
align with how it is done everywhere else.

I'm not exactly sure whether this is the right way to fix it, but it
seems to work fine.
This commit is contained in:
Nikita Popov 2013-02-01 19:48:05 +01:00
parent 2117b8edd1
commit 114245c1b9
3 changed files with 42 additions and 4 deletions

2
NEWS
View File

@ -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)

View File

@ -0,0 +1,30 @@
--TEST--
Test nested calls with die() in a generator
--FILE--
<?php
function gen() {
die('Test');
yield; // force generator
}
function function_with_3_args() {
$gen = gen();
$gen->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

View File

@ -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);
}
}