1
0
mirror of https://github.com/php/php-src.git synced 2026-03-25 16:52:18 +01:00

Fixed bug #70904 (yield from incorrectly marks valid generator as finished)

This commit is contained in:
Bob Weinand
2015-11-24 23:43:34 +01:00
parent 569763cb1a
commit 80d9dcafe0
4 changed files with 61 additions and 18 deletions

2
NEWS
View File

@@ -19,6 +19,8 @@ PHP NEWS
php_register_internal_extensions). (Lior Kaplan)
. Fixed \int (or generally every scalar type name with leading backslash)
to not be accepted as type name. (Bob)
. Fixed bug #70904 (yield from incorrectly marks valid generator as finished).
(Bob)
- Mysqlnd:
. Fixed bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction).

View File

@@ -0,0 +1,43 @@
--TEST--
Bug #70904 (yield from incorrectly marks valid generator as finished)
--FILE--
<?php
function g1() {
yield 1;
}
function g2($g1) {
yield from $g1;
echo "reached!\n";
yield 2;
}
$g1 = g1();
$g2 = g2($g1);
var_dump($g2->valid());
var_dump($g2->current());
$g1->next();
var_dump($g1->valid());
var_dump($g2->valid());
var_dump($g2->current());
$g2->next();
var_dump($g2->valid());
var_dump($g2->current());
$g2->next();
var_dump($g2->valid());
var_dump($g2->current());
?>
--EXPECT--
bool(true)
int(1)
bool(false)
bool(true)
int(1)
reached!
bool(true)
int(2)
bool(false)
NULL

View File

@@ -37,5 +37,8 @@ int(4)
int(6)
int(3)
int(5)
int(3)
int(5)
NULL
bool(false)

View File

@@ -65,12 +65,6 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution) /* {{{ */
{
zval_ptr_dtor(&generator->value);
ZVAL_UNDEF(&generator->value);
zval_ptr_dtor(&generator->key);
ZVAL_UNDEF(&generator->key);
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
zval_ptr_dtor(&generator->values);
ZVAL_UNDEF(&generator->values);
@@ -170,6 +164,10 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
zend_generator_close(generator, 0);
/* we can't immediately free them in zend_generator_close() else yield from won't be able to fetch it */
zval_ptr_dtor(&generator->value);
zval_ptr_dtor(&generator->key);
if (EXPECTED(!Z_ISUNDEF(generator->retval))) {
zval_ptr_dtor(&generator->retval);
}
@@ -508,6 +506,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
EG(current_execute_data) = original_execute_data;
} else {
ZVAL_COPY(&root->value, &root->node.parent->value);
ZVAL_COPY(ZEND_CALL_VAR(root->execute_data, yield_from->result.var), &root->node.parent->retval);
}
}
@@ -630,7 +629,7 @@ try_again:
* after the "yield from" expression. */
}
if (UNEXPECTED((orig_generator->flags & ZEND_GENERATOR_DO_INIT) != 0) && !Z_ISUNDEF(generator->value)) {
if (UNEXPECTED((orig_generator->flags & ZEND_GENERATOR_DO_INIT) != 0 && !Z_ISUNDEF(generator->value))) {
/* We must not advance Generator if we yield from a Generator being currently run */
return;
}
@@ -708,7 +707,7 @@ try_again:
static void inline zend_generator_ensure_initialized(zend_generator *generator) /* {{{ */
{
if (EXPECTED(generator->execute_data) && UNEXPECTED(Z_TYPE(generator->value) == IS_UNDEF) && EXPECTED(generator->node.parent == NULL)) {
if (UNEXPECTED(Z_TYPE(generator->value) == IS_UNDEF) && EXPECTED(generator->execute_data) && EXPECTED(generator->node.parent == NULL)) {
generator->flags |= ZEND_GENERATOR_DO_INIT;
zend_generator_resume(generator);
generator->flags &= ~ZEND_GENERATOR_DO_INIT;
@@ -759,7 +758,7 @@ ZEND_METHOD(Generator, valid)
zend_generator_get_current(generator);
RETURN_BOOL(EXPECTED(Z_TYPE(generator->value) != IS_UNDEF || generator->node.parent != NULL));
RETURN_BOOL(EXPECTED(generator->execute_data != NULL));
}
/* }}} */
@@ -778,7 +777,7 @@ ZEND_METHOD(Generator, current)
zend_generator_ensure_initialized(generator);
root = zend_generator_get_current(generator);
if (EXPECTED(Z_TYPE(root->value) != IS_UNDEF)) {
if (EXPECTED(generator->execute_data != NULL && Z_TYPE(root->value) != IS_UNDEF)) {
zval *value = &root->value;
ZVAL_DEREF(value);
@@ -802,7 +801,7 @@ ZEND_METHOD(Generator, key)
zend_generator_ensure_initialized(generator);
root = zend_generator_get_current(generator);
if (EXPECTED(Z_TYPE(root->key) != IS_UNDEF)) {
if (EXPECTED(generator->execute_data != NULL && Z_TYPE(root->key) != IS_UNDEF)) {
zval *key = &root->key;
ZVAL_DEREF(key);
@@ -865,7 +864,7 @@ ZEND_METHOD(Generator, send)
zend_generator_resume(generator);
root = zend_generator_get_current(generator);
if (EXPECTED(Z_TYPE(root->value) != IS_UNDEF)) {
if (EXPECTED(generator->execute_data)) {
zval *value = &root->value;
ZVAL_DEREF(value);
@@ -905,7 +904,7 @@ ZEND_METHOD(Generator, throw)
zend_generator_resume(generator);
root = zend_generator_get_current(generator);
if (Z_TYPE(root->value) != IS_UNDEF) {
if (generator->execute_data) {
zval *value = &root->value;
ZVAL_DEREF(value);
@@ -982,11 +981,7 @@ static int zend_generator_iterator_valid(zend_object_iterator *iterator) /* {{{
zend_generator_get_current(generator);
if (EXPECTED(Z_TYPE(generator->value) != IS_UNDEF || generator->node.parent != NULL)) {
return SUCCESS;
} else {
return FAILURE;
}
return generator->execute_data ? SUCCESS : FAILURE;
}
/* }}} */