From e25aab64268adb4e233737c274b195e1662f7211 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 11 Aug 2020 15:48:40 +0200 Subject: [PATCH] Fixed bug #79927 We need to unset the AT_FIRST_YIELD flag when yielding from an array as well. In the interest of being conservative, I'm applying this only to PHP 8. --- NEWS | 2 ++ Zend/tests/bug79927.phpt | 31 +++++++++++++++++++++++++++++++ Zend/zend_generators.c | 6 +++--- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/bug79927.phpt 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-- +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); -- 2.40.0