com php-src: Fixed bug #71818 (Memory leak when array altered in destructor): NEWS Zend/tests/bug71818.phpt Zend/zend_gc.c
| From: | Dmitry Stogov | Date: | Thu, 14 Jul 2016 09:05:44 +0000 |
| Subject: | com php-src: Fixed bug #71818 (Memory leak when array altered in destructor): NEWS Zend/tests/bug71818.phpt Zend/zend_gc.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-93007@lists.php.net to get a copy of this message | ||
Commit: 8fc934b0a1781bc0685775f4c476c6704d796a76
Author: Dmitry Stogov <dmitry@zend.com> Thu, 14 Jul 2016 12:05:44 +0300
Parents: bb2bafc7d0e9296e6dfd4035839daf2cf9498da9
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=8fc934b0a1781bc0685775f4c476c6704d796a76
Log:
Fixed bug #71818 (Memory leak when array altered in destructor)
Bugs:
https://bugs.php.net/71818
Changed paths:
M NEWS
A Zend/tests/bug71818.phpt
M Zend/zend_gc.c
Diff:
diff --git a/NEWS b/NEWS
index 7551788..01dfe0c 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ PHP NEWS
. Fixed bug #72216 (Return by reference with finally is not memory safe).
(Dmitry)
. Fixed bug #72215 (Wrong return value if var modified in finally). (Dmitry)
+ . Fixed bug #71818 (Memory leak when array altered in destructor). (Dmitry)
. Fixed bug #71539 (Memory error on $arr[$a] =& $arr[$b] if RHS rehashes)
(Dmitry, Nikita)
. Added new constant PHP_FD_SETSIZE. (cmb)
diff --git a/Zend/tests/bug71818.phpt b/Zend/tests/bug71818.phpt
new file mode 100644
index 0000000..5a7bffe
--- /dev/null
+++ b/Zend/tests/bug71818.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #71818 (Memory leak when array altered in destructor)
+--FILE--
+<?php
+class MemoryLeak
+{
+ public function __construct()
+ {
+ $this->things[] = $this;
+ }
+
+ public function __destruct()
+ {
+ $this->things[] = null;
+ }
+
+ private $things = [];
+}
+
+ini_set('memory_limit', '10M');
+
+for ($i = 0; $i < 100000; ++$i) {
+ $obj = new MemoryLeak();
+}
+echo "OK\n";
+?>
+--EXPECT--
+OK
diff --git a/Zend/zend_gc.c b/Zend/zend_gc..c
index c001efc..0e18a49 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -735,7 +735,6 @@ static void gc_add_garbage(zend_refcounted *ref, gc_additional_buffer **addition
GC_TYPE(ref) |= GC_FAKE_BUFFER_FLAG;
}
if (buf) {
- GC_REFCOUNT(ref)++;
buf->ref = ref;
buf->next = GC_G(roots).next;
buf->prev = &GC_G(roots);
@@ -898,7 +897,6 @@ static int gc_collect_roots(uint32_t *flags, gc_additional_buffer **additional_b
current = GC_G(roots).next;
while (current != &GC_G(roots)) {
- GC_REFCOUNT(current->ref)++;
if (GC_REF_GET_COLOR(current->ref) == GC_WHITE) {
count += gc_collect_white(current->ref, flags, additional_buffer);
}
@@ -939,7 +937,6 @@ tail_call:
GC_REF_GET_COLOR(ref) == GC_BLACK &&
GC_ADDRESS(GC_INFO(ref)) != GC_ROOT_BUFFER_MAX_ENTRIES)) {
GC_TRACE_REF(ref, "removing from buffer");
- GC_REFCOUNT(ref)--;
if (root) {
GC_INFO(ref) = 0;
GC_REMOVE_FROM_ROOTS(root);