mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Forbid "yield from" in force closed generators
Same check we do for "yield", was missed when "yield from" was added. We could make this more granular by only forbidding to actually yield values and still allow something like "yield from []", but this does not seem worthwhile.
This commit is contained in:
37
Zend/tests/generators/yield_from_force_closed.phpt
Normal file
37
Zend/tests/generators/yield_from_force_closed.phpt
Normal file
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
Cannot "yield from" from force closed generator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen1() {
|
||||
echo "gen1\n";
|
||||
yield 1;
|
||||
}
|
||||
|
||||
function gen2() {
|
||||
try {
|
||||
echo "try\n";
|
||||
yield from gen1();
|
||||
} finally {
|
||||
echo "finally\n";
|
||||
yield from gen1();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$gen = gen2();
|
||||
$gen->rewind();
|
||||
unset($gen);
|
||||
} catch (Error $e) {
|
||||
echo $e, "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
try
|
||||
gen1
|
||||
finally
|
||||
Error: Cannot use "yield from" in a force-closed generator in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): gen2()
|
||||
#1 {main}
|
||||
@@ -7442,6 +7442,12 @@ ZEND_VM_HANDLER(142, ZEND_YIELD_FROM, CONST|TMP|VAR|CV, ANY)
|
||||
SAVE_OPLINE();
|
||||
val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
|
||||
|
||||
if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
|
||||
zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
|
||||
FREE_OP1();
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||
ZVAL_COPY_VALUE(&generator->values, val);
|
||||
if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
|
||||
|
||||
@@ -4106,6 +4106,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
|
||||
SAVE_OPLINE();
|
||||
val = EX_CONSTANT(opline->op1);
|
||||
|
||||
if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
|
||||
zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||
ZVAL_COPY_VALUE(&generator->values, val);
|
||||
if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
|
||||
@@ -12502,6 +12508,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZE
|
||||
SAVE_OPLINE();
|
||||
val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
|
||||
|
||||
if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
|
||||
zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
|
||||
zval_ptr_dtor_nogc(free_op1);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||
ZVAL_COPY_VALUE(&generator->values, val);
|
||||
if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
|
||||
@@ -16320,6 +16332,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_VAR_HANDLER(ZE
|
||||
SAVE_OPLINE();
|
||||
val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
|
||||
|
||||
if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
|
||||
zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
|
||||
zval_ptr_dtor_nogc(free_op1);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||
ZVAL_COPY_VALUE(&generator->values, val);
|
||||
if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
|
||||
@@ -29759,6 +29777,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
|
||||
SAVE_OPLINE();
|
||||
val = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
|
||||
|
||||
if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
|
||||
zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(val) == IS_ARRAY) {
|
||||
ZVAL_COPY_VALUE(&generator->values, val);
|
||||
if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
|
||||
|
||||
Reference in New Issue
Block a user