mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fixed bug #71601 (finally block not executed after yield from)
This commit is contained in:
parent
7faf625ff3
commit
23b770f31f
3 changed files with 61 additions and 18 deletions
5
NEWS
5
NEWS
|
@ -17,6 +17,7 @@ PHP NEWS
|
|||
(Bob)
|
||||
. Fixed bug #71529 (Variable references on array elements don't work when
|
||||
using count). (Nikita)
|
||||
. Fixed bug #71601 (finally block not executed after yield from). (Bob)
|
||||
|
||||
- CLI server:
|
||||
. Fixed bug #71559 (Built-in HTTP server, we can download file in web by bug).
|
||||
|
@ -27,10 +28,10 @@ PHP NEWS
|
|||
causing date_date_set issues). (Sean DuBois)
|
||||
|
||||
- FPM:
|
||||
. Fixed #71269 (php-fpm dumped core). (Mickaël)
|
||||
. Fixed bug #71269 (php-fpm dumped core). (Mickaël)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #71584 (Possible use-after-free of ZCG(cwd) in Zend Opcache).
|
||||
. Fixed bug #71584 (Possible use-after-free of ZCG(cwd) in Zend Opcache).
|
||||
(Yussuf Khalil)
|
||||
|
||||
- PCRE:
|
||||
|
|
40
Zend/tests/generators/bug71601.phpt
Normal file
40
Zend/tests/generators/bug71601.phpt
Normal file
|
@ -0,0 +1,40 @@
|
|||
--TEST--
|
||||
Bug #71601 (finally block not executed after yield from)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen1() {
|
||||
try {
|
||||
yield 1;
|
||||
yield 2;
|
||||
return true;
|
||||
} finally {
|
||||
echo "Inner finally\n";
|
||||
}
|
||||
}
|
||||
|
||||
function gen2() {
|
||||
try {
|
||||
echo "Entered try/catch\n";
|
||||
var_dump(yield from gen1());
|
||||
} finally {
|
||||
echo "Finally\n";
|
||||
}
|
||||
}
|
||||
|
||||
$generator = gen2();
|
||||
|
||||
var_dump($generator->current());
|
||||
|
||||
unset($generator);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Entered try/catch
|
||||
int(1)
|
||||
Inner finally
|
||||
Finally
|
||||
Done
|
||||
|
|
@ -60,11 +60,6 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
|||
|
||||
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution) /* {{{ */
|
||||
{
|
||||
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
|
||||
zval_ptr_dtor(&generator->values);
|
||||
ZVAL_UNDEF(&generator->values);
|
||||
}
|
||||
|
||||
if (EXPECTED(generator->execute_data)) {
|
||||
zend_execute_data *execute_data = generator->execute_data;
|
||||
|
||||
|
@ -104,6 +99,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
|
||||
|
||||
static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*) object;
|
||||
|
@ -111,6 +108,22 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
|||
uint32_t op_num, finally_op_num, finally_op_end;
|
||||
int i;
|
||||
|
||||
/* leave yield from mode to properly allow finally execution */
|
||||
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
|
||||
zval_ptr_dtor(&generator->values);
|
||||
ZVAL_UNDEF(&generator->values);
|
||||
}
|
||||
|
||||
if (EXPECTED(generator->node.children == 0)) {
|
||||
zend_generator *root = generator->node.ptr.root, *next;
|
||||
while (UNEXPECTED(root != generator)) {
|
||||
next = zend_generator_get_child(&root->node, generator);
|
||||
OBJ_RELEASE(&root->std);
|
||||
root = next;
|
||||
}
|
||||
generator->node.parent = NULL;
|
||||
}
|
||||
|
||||
if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK))) {
|
||||
return;
|
||||
}
|
||||
|
@ -151,8 +164,6 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
|
||||
|
||||
static void zend_generator_free_storage(zend_object *object) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator*) object;
|
||||
|
@ -176,15 +187,6 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
|
|||
if (generator->iterator) {
|
||||
zend_iterator_dtor(generator->iterator);
|
||||
}
|
||||
|
||||
if (EXPECTED(generator->node.children == 0)) {
|
||||
zend_generator *root = generator->node.ptr.root, *next;
|
||||
while (UNEXPECTED(root != generator)) {
|
||||
next = zend_generator_get_child(&root->node, generator);
|
||||
OBJ_RELEASE(&root->std);
|
||||
root = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue