Fixed bug causing exception not being thrown immediately into a generator yielding from an array

This commit is contained in:
Bob Weinand 2015-11-25 23:09:44 +01:00
parent 071247713f
commit 2de8915dea
3 changed files with 51 additions and 0 deletions

2
NEWS
View file

@ -16,6 +16,8 @@ PHP NEWS
to not be accepted as type name. (Bob)
. Fixed bug #70904 (yield from incorrectly marks valid generator as finished).
(Bob)
. Fixed exception not being thrown immediately into a generator yielding
from an array. (Bob)
- Mysqlnd:
. Fixed bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction).

View file

@ -0,0 +1,43 @@
--TEST--
Throwing into a generator yielding from an array/iterator
--FILE--
<?php
$data = [1, 2, 3];
function yielditer($arr) {
foreach($arr as $val) {
yield $val;
}
}
function yf($in) {
yield from $in;
}
function test($g) {
var_dump($g->current());
try {
$g->throw(new Exception("Exception!"));
} catch (Exception $e) {
echo "{$e->getMessage()}\n";
}
var_dump($g->current());
}
$yfiter = yf($data);
$yfgen = yf(yielditer($data));
test(yf($data));
echo "\n";
test(yf(yielditer($data)));
?>
--EXPECT--
int(1)
Exception!
NULL
int(1)
Exception!
NULL

View file

@ -287,6 +287,12 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_
static void zend_generator_throw_exception(zend_generator *generator, zval *exception)
{
/* if we don't stop an array/iterator yield from, the exception will only reach the generator after the values were all iterated over */
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
zval_ptr_dtor(&generator->values);
ZVAL_UNDEF(&generator->values);
}
/* Throw the exception in the context of the generator. Decrementing the opline
* to pretend the exception happened during the YIELD opcode. */
zend_execute_data *original_execute_data = EG(current_execute_data);