com php-src: Fix bug #65764: NEWS Zend/tests/generators/throw _caught.phpt Zend/tests/generators/throw_rethrow.phpt Zend/zend_generators.c
| From: | Nikita Popov | Date: | Sun, 01 Dec 2013 12:37:56 +0000 |
| Subject: | com php-src: Fix bug #65764: NEWS Zend/tests/generators/throw _caught.phpt Zend/tests/generators/throw_rethrow.phpt Zend/zend_generators.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-74190@lists.php.net to get a copy of this message | ||
Commit: 02dca18b9045029e75d672b8667c1411dde5ca34
Author: Nikita Popov <nikic@php.net> Sun, 1 Dec 2013 13:37:56 +0100
Parents: af60886962133e49662ee0e5090d04bf5705bdcc
Branches: PHP-5.5 PHP-5.6 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=02dca18b9045029e75d672b8667c1411dde5ca34
Log:
Fix bug #65764
I'm not exactly sure whether this is the right way to fix it. The
question is whether Generator::throw() on a newborn generator (i.e.
a generator that is not yet at yield expression) should first advance to
the first yield and throw the exception there or whether it should
instead throw the exception in the caller's context.
The old behavior was to throw it at the start of the function (i.e.
the very first opcode), which causes issues like the one in #65764.
Effectively it's impossible to properly handle the exceptions in this
case.
For now I choose the variant where the generator advances to the
first yield before throwing, as that's consistent with how all other
methods on the Generator object currently behave. This does not
necessarily match the behavior in other languages, e.g. Python would throw
the exception in the caller's context. But then our send() method already
has this kind of deviation, so it stays internally consistent at least.
Bugs:
https://bugs.php.net/65764
Changed paths:
M NEWS
M Zend/tests/generators/throw_caught.phpt
M Zend/tests/generators/throw_rethrow.phpt
M Zend/zend_generators.c
Diff:
diff --git a/NEWS b/NEWS
index 6afb736..f4b3bf8 100644
--- a/NEWS
+++ b/NEWS
@@ -4,8 +4,10 @@ PHP NEWS
- Core:
. Added validation of class names in the autoload process. (Dmitry)
- . Fixed buf #66041 (list() fails to unpack yielded ArrayAccess object).
+ . Fixed bug #66041 (list() fails to unpack yielded ArrayAccess object).
(Nikita)
+ . Fixed bug #65764 (generators/throw_rethrow FAIL with
+ ZEND_COMPILE_EXTENDED_INFO). (Nikita)
- Date:
. Fixed bug #66060 (Heap buffer over-read in DateInterval). (Remi)
diff --git a/Zend/tests/generators/throw_caught.phpt b/Zend/tests/generators/throw_caught.phpt
index 0c3f8e9..c5e9d81 100644
--- a/Zend/tests/generators/throw_caught.phpt
+++ b/Zend/tests/generators/throw_caught.phpt
@@ -4,6 +4,7 @@ Generator::throw() where the exception is caught in the generator
<?php
function gen() {
+ echo "before yield\n";
try {
yield;
} catch (RuntimeException $e) {
@@ -18,6 +19,7 @@ var_dump($gen->throw(new RuntimeException('Test')));
?>
--EXPECTF--
+before yield
exception 'RuntimeException' with message 'Test' in %s:%d
Stack trace:
#0 {main}
diff --git a/Zend/tests/generators/throw_rethrow.phpt b/Zend/tests/generators/throw_rethrow.phpt
index 267f5f0..65044ee 100644
--- a/Zend/tests/generators/throw_rethrow.phpt
+++ b/Zend/tests/generators/throw_rethrow.phpt
@@ -4,6 +4,7 @@ Generator::throw() where the generator throws a different exception
<?php
function gen() {
+ echo "before yield\n";
try {
yield;
} catch (RuntimeException $e) {
@@ -18,6 +19,7 @@ var_dump($gen->throw(new RuntimeException('throw')));
?>
--EXPECTF--
+before yield
Caught: exception 'RuntimeException' with message 'throw' in %s:%d
Stack trace:
#0 {main}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index bc3d6d9..ec9e9b8 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -560,6 +560,8 @@ ZEND_METHOD(Generator, throw)
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
if (generator->execute_data) {
/* Throw the exception in the context of the generator */
zend_execute_data *current_execute_data = EG(current_execute_data);