]> granicus.if.org Git - php/commitdiff
Fixed bug #75396
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 12 Jan 2018 20:24:04 +0000 (21:24 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 12 Jan 2018 20:27:23 +0000 (21:27 +0100)
Do not run finally blocks in generators on unclean shutdown (e.g.
caused by exit). This is consistent with how finally blocks outside
of generators behave.

NEWS
Zend/tests/generators/bug75396.phpt [new file with mode: 0644]
Zend/zend_generators.c

diff --git a/NEWS b/NEWS
index 4889178d26ed095aac2d09677b7eb6b19ef546ab..23dccb02baacb112d6af28fc8b1cbeb64edd432e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ PHP                                                                        NEWS
   . Fixed bug #75786 (segfault when using spread operator on generator passed
     by reference). (Nikita)
   . Fixed bug #75799 (arg of get_defined_functions is optional). (carusogabriel)
+  . Fixed bug #75396 (Exit inside generator finally results in fatal error).
+    (Nikita)
 
 - Opcache:
   . Fixed bug #75720 (File cache not populated after SHM runs full). (Dmitry)
diff --git a/Zend/tests/generators/bug75396.phpt b/Zend/tests/generators/bug75396.phpt
new file mode 100644 (file)
index 0000000..6d5abf5
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #75396: Exit inside generator finally results in fatal error
+--FILE--
+<?php
+
+$gen = (function () {
+    yield 42;
+
+    try {
+        echo "Try\n";
+        exit("Exit\n");
+    } finally {
+        echo "Finally\n";
+    }
+})();
+
+$gen->send("x");
+
+?>
+--EXPECT--
+Try
+Exit
index 8ce641286d44b5269141a33e65d5dca94e5b6dcd..69fa17f74fc8ff180f4d0a9859f71a90cc91625f 100644 (file)
@@ -185,7 +185,8 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
                generator->node.parent = NULL;
        }
 
-       if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK))) {
+       if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK))
+                       || CG(unclean_shutdown)) {
                return;
        }