From: Nikita Popov Date: Sat, 29 Jun 2013 19:51:54 +0000 (+0200) Subject: Don't try to clean up generator stack on unclean shutdown X-Git-Tag: php-5.5.2RC1~17^2~21^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f36224beb61b8d0b189c447bdb44ee2d73be637;p=php Don't try to clean up generator stack on unclean shutdown This fixes bugs #65035 and #65161. In one of the bugs the issue is that function_state.arguments is NULL, but the arg count is pushed to the stack and the code tries to free it. In the other bug the stack of the generator is freed twice, once in generator_close and later during shutdown. It's rather hard (if at all possible) to do a proper stack cleanup on an unclean shutdown, so I'm just disabling it in this case. --- diff --git a/NEWS b/NEWS index 6122e0369b..4cbd4e8e11 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS (Adam) . Fixed bug #65108 (is_callable() triggers Fatal Error). (David Soria Parra, Laruence) + . Fixed bug #65035 (yield / exit segfault). (Nikita) + . Fixed bug #65161 (Generator + autoload + syntax error = segfault). (Nikita) - OPcache . Fixed bug #64827 (Segfault in zval_mark_grey (zend_gc.c)). (Laruence) diff --git a/Zend/tests/generators/bug65035.phpt b/Zend/tests/generators/bug65035.phpt new file mode 100644 index 0000000000..18276cc23a --- /dev/null +++ b/Zend/tests/generators/bug65035.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #65035: yield / exit segfault +--FILE-- +current(); + +?> +--EXPECT-- +Done diff --git a/Zend/tests/generators/bug65161.phpt b/Zend/tests/generators/bug65161.phpt new file mode 100644 index 0000000000..215c1880e3 --- /dev/null +++ b/Zend/tests/generators/bug65161.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #65161: Generator + autoload + syntax error = segfault +--FILE-- + +--EXPECTF-- +Fatal error: Call to undefined function foo() in %s on line %d diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index d189148f47..4b22eb242e 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -55,6 +55,12 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished zval_ptr_dtor(&execute_data->current_this); } + /* A fatal error / die occured during the generator execution. Trying to clean + * up the stack may not be safe in this case. */ + if (CG(unclean_shutdown)) { + return; + } + /* If the generator is closed before it can finish execution (reach * a return statement) we have to free loop variables manually, as * we don't know whether the SWITCH_FREE / FREE opcodes have run */