Skip to content

Commit 897d99c

Browse files
committed
Rethrow generator exception even without active stack frame
Finally blocks in generators may be invoked during shutdown, in which case we don't have a stack frame. Similar to what zend_call_function does, we still need to rethrow these exceptions, otherwise they will be hidden (and leak).
1 parent 189f625 commit 897d99c

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Generator exceptions during shutdown should not be swallowed
3+
--FILE--
4+
<?php
5+
6+
function gen() {
7+
try {
8+
echo "before yield\n";
9+
yield;
10+
echo "after yield\n";
11+
} finally {
12+
echo "before yield in finally\n";
13+
yield;
14+
echo "after yield in finally\n";
15+
}
16+
echo "after finally\n";
17+
}
18+
19+
$gen = gen();
20+
$gen->rewind();
21+
22+
?>
23+
--EXPECTF--
24+
before yield
25+
before yield in finally
26+
27+
Fatal error: Uncaught Error: Cannot yield from finally in a force-closed generator in %s:%d
28+
Stack trace:
29+
#0 {main}
30+
thrown in %s on line %d

Zend/zend_generators.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,9 +827,10 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
827827
if (UNEXPECTED(EG(exception) != NULL)) {
828828
if (generator == orig_generator) {
829829
zend_generator_close(generator, 0);
830-
if (EG(current_execute_data) &&
831-
EG(current_execute_data)->func &&
832-
ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
830+
if (!EG(current_execute_data)) {
831+
zend_throw_exception_internal(NULL);
832+
} else if (EG(current_execute_data)->func &&
833+
ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
833834
zend_rethrow_exception(EG(current_execute_data));
834835
}
835836
} else {

0 commit comments

Comments
 (0)