]> granicus.if.org Git - php/commitdiff
Fixed bug #71067 (Local object in class method stays in memory for each call)
authorXinchen Hui <laruence@gmail.com>
Wed, 9 Dec 2015 13:07:59 +0000 (21:07 +0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 9 Dec 2015 13:07:59 +0000 (21:07 +0800)
NEWS
Zend/tests/bug71067.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/NEWS b/NEWS
index 33bd38cc5525057525a2a9c2ecf2fd09aed205a3..8766bbbbffbe94144de98f572a5f44703f488e1e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? Jan 2016 PHP 7.0.2
 
+- Core:
+  . Fixed bug #71067 (Local object in class method stays in memory for each
+    call). (Laruence)
+
 - Mbstring:
   . Fixed bug #71066 (mb_send_mail: Program terminated with signal SIGSEGV,
     Segmentation fault). (Laruence)
diff --git a/Zend/tests/bug71067.phpt b/Zend/tests/bug71067.phpt
new file mode 100644 (file)
index 0000000..b2a1b31
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+Bug #71067 (Local object in class method stays in memory for each call)
+--INI--
+opcache.enable=0
+error_reporting=0
+--FILE--
+<?php
+class Test {
+       public function test(){
+               $arr = (object) [
+                       'children' => []
+               ];
+               $arr->children[] = 1;
+               return $arr;
+       }
+}
+
+$o = new Test();
+$o->test();
+
+print_r($o->test());
+?>
+--EXPECT--
+stdClass Object
+(
+    [children] => Array
+        (
+            [0] => 1
+        )
+
+)
index f851833a2df6feddf98a672380ab65579ae48eca..2ca3114cc7420b165bd5fbbf109f2ebb422d2346 100644 (file)
@@ -1954,6 +1954,12 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
                                return;
                        }
                } else if (EXPECTED(zobj->properties != NULL)) {
+                       if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+                               if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+                                       GC_REFCOUNT(zobj->properties)--;
+                               }
+                               zobj->properties = zend_array_dup(zobj->properties);
+                       }
                        retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
                        if (EXPECTED(retval)) {
                                ZVAL_INDIRECT(result, retval);