Skip to content

Prevent resumption of generator suspended in yield from #19315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Zend/tests/gh19306.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
GH-19306: Generator suspended in yield from may be resumed
--FILE--
<?php

class It implements IteratorAggregate
{
public function getIterator(): Generator
{
yield "";
Fiber::suspend();
}
}
function g()
{
yield from new It();
}
$a = g();
$fiber = new Fiber(function () use ($a) {
echo "Fiber start\n";
$a->next();
echo "Fiber return\n";
});
$fiber->start();
echo "Fiber suspended\n";
try {
$a->next();
} catch (Throwable $t) {
echo $t->getMessage(), "\n";
}
echo "Destroying fiber\n";
$fiber = null;
echo "Shutdown\n";
?>
--EXPECT--
Fiber start
Fiber suspended
Cannot resume an already running generator
Destroying fiber
Shutdown
5 changes: 3 additions & 2 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
orig_generator->execute_fake.prev_execute_data = original_execute_data;
}

generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;

/* Ensure this is run after executor_data swap to have a proper stack trace */
if (UNEXPECTED(!Z_ISUNDEF(generator->values))) {
if (EXPECTED(zend_generator_get_next_delegated_value(generator) == SUCCESS)) {
Expand All @@ -795,7 +797,7 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
EG(jit_trace_num) = original_jit_trace_num;

orig_generator->flags &= ~(ZEND_GENERATOR_DO_INIT | ZEND_GENERATOR_IN_FIBER);
generator->flags &= ~ZEND_GENERATOR_IN_FIBER;
generator->flags &= ~(ZEND_GENERATOR_CURRENTLY_RUNNING | ZEND_GENERATOR_IN_FIBER);
return;
}
if (UNEXPECTED(EG(exception))) {
Expand All @@ -817,7 +819,6 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
}

/* Resume execution */
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
if (!ZEND_OBSERVER_ENABLED) {
zend_execute_ex(generator->execute_data);
} else {
Expand Down
Loading