diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2016-02-15 22:37:21 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2016-02-15 22:37:21 +0100 |
commit | 23b770f31fdf893239a185bdb36876c5438eb813 (patch) | |
tree | ba85b0262c82aa026dde0098f9f19424b09fd5b0 | |
parent | 7faf625ff3f2bc27d399967d3505b44595446913 (diff) | |
download | php-git-23b770f31fdf893239a185bdb36876c5438eb813.tar.gz |
Fixed bug #71601 (finally block not executed after yield from)
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | Zend/tests/generators/bug71601.phpt | 40 | ||||
-rw-r--r-- | Zend/zend_generators.c | 34 |
3 files changed, 61 insertions, 18 deletions
@@ -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: diff --git a/Zend/tests/generators/bug71601.phpt b/Zend/tests/generators/bug71601.phpt new file mode 100644 index 0000000000..e3f21692e7 --- /dev/null +++ b/Zend/tests/generators/bug71601.phpt @@ -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 + diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index f8087fc943..646e46b676 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -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; - } - } } /* }}} */ |