summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug79927.phpt31
-rw-r--r--Zend/zend_generators.c6
3 files changed, 36 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index c890b29c9a..cd163a5f6c 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,8 @@ PHP NEWS
exit value in CLI). (Nikita)
. Fixed bug #62294 (register_shutdown_function() does not correctly handle
exit code). (Nikita)
+ . Fixed bug #79927 (Generator doesn't throw exception after multiple yield
+ from iterable). (Nikita)
- Date:
. Fixed bug #60302 (DateTime::createFromFormat should new static(), not new
diff --git a/Zend/tests/bug79927.phpt b/Zend/tests/bug79927.phpt
new file mode 100644
index 0000000000..df8f245ddf
--- /dev/null
+++ b/Zend/tests/bug79927.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #79927: Generator doesn't throw exception after multiple yield from iterable
+--FILE--
+<?php
+
+$generator = (function () {
+ yield from [1, 2, 3];
+})();
+
+$generator->next();
+$generator->next();
+try {
+ $generator->rewind();
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+echo $generator->current(), "\n";
+
+$generator2 = (function () {
+ yield from [];
+ yield 4;
+})();
+$generator2->current();
+$generator2->rewind();
+echo $generator2->current(), "\n";
+
+?>
+--EXPECT--
+Cannot rewind a generator that was already run
+3
+4
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 0d2d7e4a4d..040a213ce7 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -731,6 +731,9 @@ try_again:
return;
}
+ /* Drop the AT_FIRST_YIELD flag */
+ orig_generator->flags &= ~ZEND_GENERATOR_AT_FIRST_YIELD;
+
if (UNEXPECTED(!Z_ISUNDEF(generator->values))) {
if (EXPECTED(zend_generator_get_next_delegated_value(generator) == SUCCESS)) {
orig_generator->flags &= ~ZEND_GENERATOR_DO_INIT;
@@ -740,9 +743,6 @@ try_again:
* after the "yield from" expression. */
}
- /* Drop the AT_FIRST_YIELD flag */
- orig_generator->flags &= ~ZEND_GENERATOR_AT_FIRST_YIELD;
-
{
/* Backup executor globals */
zend_execute_data *original_execute_data = EG(current_execute_data);