com php-src: Fixed bug #69446 (GC leak relating to removal of nested data after dtors run): Zend/tests/bug64896.phpt Zend/tests/bug69446.phpt
Zend/tests/bug69446_2.phpt Zend/zend_gc.c

From: Date: Tue, 14 Apr 2015 16:53:56 +0000
Subject: com php-src: Fixed bug #69446 (GC leak relating to removal of nested data after dtors run): Zend/tests/bug64896.phpt Zend/tests/bug69446.phpt
Zend/tests/bug69446_2.phpt Zend/zend_gc.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-86242@lists.php.net to get a copy of this message
Commit: 00445ba22dd97988009692e2b35edaeff715f5e1 Author: Dmitry Stogov <dmitry@zend.com> Tue, 14 Apr 2015 19:53:56 +0300 Parents: 2256dbfb215f07f6147d011a0761dcca84a25f22 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=00445ba22dd97988009692e2b35edaeff715f5e1 Log: Fixed bug #69446 (GC leak relating to removal of nested data after dtors run) Bugs: https://bugs.php.net/69446 Changed paths: M Zend/tests/bug64896.phpt A Zend/tests/bug69446.phpt A Zend/tests/bug69446_2.phpt M Zend/zend_gc.c Diff: diff --git a/Zend/tests/bug64896.phpt b/Zend/tests/bug64896.phpt index f019697..3ff4a21 100644 --- a/Zend/tests/bug64896.phpt +++ b/Zend/tests/bug64896.phpt @@ -30,6 +30,7 @@ gc_disable(); unserialize(serialize($foo)); gc_collect_cycles(); var_dump($bar); +gc_enable(); /* will output: object(bad)#4 (1) { ["_private":"bad":private]=> diff --git a/Zend/tests/bug69446.phpt b/Zend/tests/bug69446.phpt new file mode 100644 index 0000000..b448a2b --- /dev/null +++ b/Zend/tests/bug69446.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #69446 (GC leak relating to removal of nested data after dtors run) +--FILE-- +<?php +$bar = NULL; +class bad { + public function __destruct() { + global $bar; + $bar = $this; + $bar->y = new stdClass; + } +} + +$foo = new stdClass; +$foo->foo = $foo; +$foo->bad = new bad; +$foo->bad->x = new stdClass; + +unset($foo); +gc_collect_cycles(); +var_dump($bar); +--EXPECT-- +object(bad)#2 (2) { + ["x"]=> + object(stdClass)#3 (0) { + } + ["y"]=> + object(stdClass)#4 (0) { + } +} diff --git a/Zend/tests/bug69446_2.phpt b/Zend/tests/bug69446_2.phpt new file mode 100644 index 0000000..520bd1f --- /dev/null +++ b/Zend/tests/bug69446_2.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #69446 (GC leak relating to removal of nested data after dtors run) +--FILE-- +<?php +$bar = NULL; +class bad +{ + public $_private = array(); + + public function __construct() + { + $this->_private[] = 'php'; + } + + public function __destruct() + { + global $bar; + $bar = $this; + } +} + +$foo = new stdclass; +$foo->foo = $foo; +$foo->bad = new bad; + +unserialize(serialize($foo)); +//unset($foo); + +gc_collect_cycles(); +var_dump($bar); +--EXPECT-- +object(bad)#4 (1) { + ["_private"]=> + array(1) { + [0]=> + string(3) "php" + } +} diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 8669db1..d5c8ea8 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -720,7 +720,6 @@ static int gc_collect_roots(uint32_t *flags) current = GC_G(roots).next; while (current != &GC_G(roots)) { if (GC_REF_GET_COLOR(current->ref) == GC_WHITE) { - GC_REFCOUNT(current->ref)++; count += gc_collect_white(current->ref, flags); } current = current->next; @@ -832,7 +831,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref) Bucket *p, *end; tail_call: - if (GC_ADDRESS(GC_INFO(ref)) != 0) { + if (GC_ADDRESS(GC_INFO(ref)) != 0 && GC_REF_GET_COLOR(ref) == GC_BLACK) { GC_TRACE_REF(ref, "removing from buffer"); GC_REMOVE_FROM_BUFFER(ref);

« previous php.cvs (#86242) next »