Skip to content

Commit

Permalink
Fix bug #63830: Segfault on undefined function call in nested generator
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Feb 1, 2013
1 parent 2117b8e commit 114245c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 30 additions & 0 deletions Zend/tests/generators/nested_calls_with_die.phpt
Original file line number Diff line number Diff line change
@@ -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
14 changes: 10 additions & 4 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down

0 comments on commit 114245c

Please sign in to comment.