Commit: 114245c1b9cf153583c918e130faccc1f61d3ba5 Author: Nikita Popov <ni...@php.net> Fri, 1 Feb 2013 19:48:05 +0100 Parents: 2117b8edd1efd9940da8e5c4549e0ce13e92894c Branches: PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=114245c1b9cf153583c918e130faccc1f61d3ba5 Log: 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. Bugs: https://bugs.php.net/63830 Changed paths: M NEWS A Zend/tests/generators/nested_calls_with_die.phpt M Zend/zend_generators.c Diff: diff --git a/NEWS b/NEWS index 14c77d0..e79cffe 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 0000000..f43d89b --- /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-- +<?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 diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 6213206..c1dbee1 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); } } -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php