From: Dmitry Stogov Date: Wed, 5 Sep 2012 05:50:55 +0000 (+0400) Subject: Fixed bug #62991 (Segfault with generator and closure) X-Git-Tag: php-5.5.0alpha1~20^2~24^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72473962a9722ee0a8107909f32c145d3b44f906;p=php Fixed bug #62991 (Segfault with generator and closure) --- diff --git a/Zend/tests/bug62991.phpt b/Zend/tests/bug62991.phpt new file mode 100644 index 0000000000..cb4ff93359 --- /dev/null +++ b/Zend/tests/bug62991.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #62991 (Segfault with generator and closure) +--FILE-- + +--EXPECT-- +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +okey diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index c22d745bc3..3d4fdd2c5f 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -154,6 +154,12 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio efree(prev_execute_data); } + /* Free a clone of closure */ + if (op_array->fn_flags & ZEND_ACC_CLOSURE) { + destroy_op_array(op_array TSRMLS_CC); + efree(op_array); + } + efree(execute_data); generator->execute_data = NULL; } @@ -358,6 +364,14 @@ zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */ zval *return_value; zend_generator *generator; + /* Create a clone of closure, because it may be destroyed */ + if (op_array->fn_flags & ZEND_ACC_CLOSURE) { + zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array)); + *op_array_copy = *op_array; + function_add_ref(op_array_copy); + op_array = op_array_copy; + } + /* Create new execution context. We have to back up and restore * EG(current_execute_data) and EG(opline_ptr) here because the function * modifies it. */