]> granicus.if.org Git - php/commitdiff
Fixed bug #71297 (Memory leak with yield from)
authorBob Weinand <bobwei9@hotmail.com>
Thu, 7 Jan 2016 10:56:10 +0000 (11:56 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Thu, 7 Jan 2016 10:56:21 +0000 (11:56 +0100)
NEWS
Zend/tests/generators/bug71297.phpt [new file with mode: 0644]
Zend/zend_generators.c

diff --git a/NEWS b/NEWS
index 758b70e21f2ace7ad2640ddd07430fb6c63f8294..d33a8fdc4f179902612f78d952a256a5e688167c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ PHP                                                                        NEWS
     (Bob)
   . Fixed bug #71273 (A wrong ext directory setup in php.ini leads to crash).
     (Anatol)
+  . Fixed bug #71297 (Memory leak with consecutive yield from). (Bob)
 
 - CURL:
   . Fixed bug #71225 (curl_setopt() fails to set CURLOPT_POSTFIELDS with
diff --git a/Zend/tests/generators/bug71297.phpt b/Zend/tests/generators/bug71297.phpt
new file mode 100644 (file)
index 0000000..eed7278
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Bug #71297 (Memory leak with consecutive yield from)
+--FILE--
+<?php
+
+function foo() {
+       yield array_fill(0, 10000, 4);
+}
+
+function genLeak() {
+       $i = 0;
+       while (1) {
+               yield from foo();
+               print $i++;
+       }
+}
+
+$x = 0;
+foreach (genLeak() as $i) {
+       if ($x++ == 3) break;
+}
+
+?>
+--EXPECT--
+012
index b5e6c6a2215d7958b2a0ea689a580fed770b0a83..09cbb9a5ee21d885ea26beefb1ecdfb05fd5c480 100644 (file)
@@ -495,7 +495,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
                        if (EXPECTED(EG(exception) == NULL)) {
                                zend_op *yield_from = (zend_op *) root->execute_data->opline - 1;
 
-                               if (yield_from->opcode == ZEND_YIELD_FROM && !(yield_from->result_type & EXT_TYPE_UNUSED)) {
+                               if (yield_from->opcode == ZEND_YIELD_FROM) {
                                        if (Z_ISUNDEF(root->node.parent->retval)) {
                                                /* Throw the exception in the context of the generator */
                                                zend_execute_data *original_execute_data = EG(current_execute_data);
@@ -512,6 +512,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
 
                                                EG(current_execute_data) = original_execute_data;
                                        } else {
+                                               zval_dtor(&root->value);
                                                ZVAL_COPY(&root->value, &root->node.parent->value);
                                                ZVAL_COPY(ZEND_CALL_VAR(root->execute_data, yield_from->result.var), &root->node.parent->retval);
                                        }