]> granicus.if.org Git - php/commitdiff
Fixed bug #71601 (finally block not executed after yield from)
authorBob Weinand <bobwei9@hotmail.com>
Mon, 15 Feb 2016 21:37:21 +0000 (22:37 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Mon, 15 Feb 2016 21:37:21 +0000 (22:37 +0100)
NEWS
Zend/tests/generators/bug71601.phpt [new file with mode: 0644]
Zend/zend_generators.c

diff --git a/NEWS b/NEWS
index ec278295d9b7d1f9918e6f327056fa969775f917..15667a6958cec76b292c74d097211c88cdf0df8b 100644 (file)
--- 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 (file)
index 0000000..e3f2169
--- /dev/null
@@ -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
+
index f8087fc943a457162780d66342dc025b5886da61..646e46b6764c2d2d62429e4848358dcffedcc0f7 100644 (file)
@@ -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;
-               }
-       }
 }
 /* }}} */