]> granicus.if.org Git - php/commitdiff
Fix ClosedGeneratorException possibly thrown into wrong scope
authorBob Weinand <bobwei9@hotmail.com>
Sat, 23 Jul 2016 14:39:21 +0000 (16:39 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Sat, 23 Jul 2016 14:39:21 +0000 (16:39 +0200)
NEWS
Zend/tests/generators/mutli_yield_from_with_exception.phpt
Zend/zend_generators.c

diff --git a/NEWS b/NEWS
index bc7b3d970dd1f8771ed073e9b624cfd57a60d09f..3909a2c3c6ad122f6301f52a9ba734b190bd41f6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@ PHP                                                                        NEWS
   . Fixed bug #72024 (microtime() leaks memory). (maroszek at gmx dot net)
   . Fixed bug #71911 (Unable to set --enable-debug on building extensions by
     phpize on Windows). (Yuji Uchiyama)
+  . Fixed bug causing ClosedGeneratorException being thrown into the calling
+    code instead of the Generator yielding from. (Bob)
 
 - COM:
   . Fixed bug #72569 (DOTNET/COM array parameters broke in PHP7). (Anatol)
index 2dc71815f0e10f2873d83879777a1e3ab949617e..4be2449a4667a6efc872925189f5d28913805e82 100644 (file)
@@ -40,11 +40,10 @@ Stack trace:
 #2 %s(%d): Generator->next()
 #3 {main}
 Generator 1
-
-Fatal error: Uncaught ClosedGeneratorException: Generator yielded from aborted, no return value available in %s:%d
+Caught exception!
+ClosedGeneratorException: Generator yielded from aborted, no return value available in %s:%d
 Stack trace:
 #0 [internal function]: gen(Object(Generator))
 #1 %s(%d): Generator->current()
 #2 {main}
-  thrown in %s on line %d
-
+NULL
index 89b919a48c2d10a334804ce746eaae74d92c8fd0..f1cc09e9380b183d1e8ffe39b5b0798d96d62e4e 100644 (file)
@@ -521,6 +521,16 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
                                                zend_throw_exception(zend_ce_ClosedGeneratorException, "Generator yielded from aborted, no return value available", 0);
 
                                                EG(current_execute_data) = original_execute_data;
+
+                                               if (!((old_root ? old_root : generator)->flags & ZEND_GENERATOR_CURRENTLY_RUNNING)) {
+                                                       leaf->node.ptr.root = root;
+                                                       root->node.parent = NULL;
+                                                       if (old_root) {
+                                                               OBJ_RELEASE(&old_root->std);
+                                                       }
+                                                       zend_generator_resume(leaf);
+                                                       return leaf->node.ptr.root; /* this may be updated during zend_generator_resume! */
+                                               }
                                        } else {
                                                zval_ptr_dtor(&root->value);
                                                ZVAL_COPY(&root->value, &root->node.parent->value);