com php-src: Fixed bug #71601 (finally block not executed after yield from): NEWS Zend/tests/generators/bug71601.phpt Zend/zend_gen erators.c
| From: | Bob Weinand | Date: | Mon, 15 Feb 2016 21:37:21 +0000 |
| Subject: | com php-src: Fixed bug #71601 (finally block not executed after yield from): NEWS Zend/tests/generators/bug71601.phpt Zend/zend_gen erators.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-91060@lists.php.net to get a copy of this message | ||
Commit: 23b770f31fdf893239a185bdb36876c5438eb813
Author: Bob Weinand <bobwei9@hotmail.com> Mon, 15 Feb 2016 22:37:21 +0100
Parents: 7faf625ff3f2bc27d399967d3505b44595446913
Branches: PHP-7.0
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=23b770f31fdf893239a185bdb36876c5438eb813
Log:
Fixed bug #71601 (finally block not executed after yield from)
Bugs:
https://bugs.php.net/71601
Changed paths:
M NEWS
A Zend/tests/generators/bug71601.phpt
M Zend/zend_generators.c
Diff:
diff --git a/NEWS b/NEWS
index ec27829..15667a6 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ PHP NEWS
(Bob)
. Fixed bug #71529 (Variable references on array elements don't work when
using count). (Nikita)
+ . Fixed bug #71601 (finally block not executed after yield from). (Bob)
- CLI server:
. Fixed bug #71559 (Built-in HTTP server, we can download file in web by bug).
@@ -27,10 +28,10 @@ PHP NEWS
causing date_date_set issues). (Sean DuBois)
- FPM:
- . Fixed #71269 (php-fpm dumped core). (Mickaël)
+ . Fixed bug #71269 (php-fpm dumped core). (Mickaël)
- Opcache:
- . Fixed bug #71584 (Possible use-after-free of ZCG(cwd) in Zend Opcache).
+ . Fixed bug #71584 (Possible use-after-free of ZCG(cwd) in Zend Opcache).
(Yussuf Khalil)
- PCRE:
diff --git a/Zend/tests/generators/bug71601.phpt b/Zend/tests/generators/bug71601.phpt
new file mode 100644
index 0000000..e3f2169
--- /dev/null
+++ b/Zend/tests/generators/bug71601.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #71601 (finally block not executed after yield from)
+--FILE--
+<?php
+
+function gen1() {
+ try {
+ yield 1;
+ yield 2;
+ return true;
+ } finally {
+ echo "Inner finally\n";
+ }
+}
+
+function gen2() {
+ try {
+ echo "Entered try/catch\n";
+ var_dump(yield from gen1());
+ } finally {
+ echo "Finally\n";
+ }
+}
+
+$generator = gen2();
+
+var_dump($generator->current());
+
+unset($generator);
+
+echo "Done\n";
+
+?>
+--EXPECT--
+Entered try/catch
+int(1)
+Inner finally
+Finally
+Done
+
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index f8087fc..646e46b 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -60,11 +60,6 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution) /* {{{
*/
{
- if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
- zval_ptr_dtor(&generator->values);
- ZVAL_UNDEF(&generator->values);
- }
-
if (EXPECTED(generator->execute_data)) {
zend_execute_data *execute_data = generator->execute_data;
@@ -104,6 +99,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
}
/* }}} */
+static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
+
static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
@@ -111,6 +108,22 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
uint32_t op_num, finally_op_num, finally_op_end;
int i;
+ /* leave yield from mode to properly allow finally execution */
+ if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
+ zval_ptr_dtor(&generator->values);
+ ZVAL_UNDEF(&generator->values);
+ }
+
+ if (EXPECTED(generator->node.children == 0)) {
+ zend_generator *root = generator->node.ptr.root, *next;
+ while (UNEXPECTED(root != generator)) {
+ next = zend_generator_get_child(&root->node, generator);
+ OBJ_RELEASE(&root->std);
+ root = next;
+ }
+ generator->node.parent = NULL;
+ }
+
if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags &
ZEND_ACC_HAS_FINALLY_BLOCK))) {
return;
}
@@ -151,8 +164,6 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
}
/* }}} */
-static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
-
static void zend_generator_free_storage(zend_object *object) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
@@ -176,15 +187,6 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
if (generator->iterator) {
zend_iterator_dtor(generator->iterator);
}
-
- if (EXPECTED(generator->node.children == 0)) {
- zend_generator *root = generator->node.ptr.root, *next;
- while (UNEXPECTED(root != generator)) {
- next = zend_generator_get_child(&root->node, generator);
- OBJ_RELEASE(&root->std);
- root = next;
- }
- }
}
/* }}} */