From 589542f50cbaf2bfc88aea79092df9db54f75ac6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 26 Aug 2019 17:48:05 +0200 Subject: Remove properties HT from nested GC data The properties HT may be a GC root itself, so we need to remove it. I'm not sure this issue actually applies to PHP 7.2, but committing it there to be safe. As seen from the test case, the handling here is rather buggy on 7.2. --- Zend/tests/gc_042.phpt | 26 ++++++++++++++++++++++++++ Zend/zend_gc.c | 4 ++++ 2 files changed, 30 insertions(+) create mode 100644 Zend/tests/gc_042.phpt diff --git a/Zend/tests/gc_042.phpt b/Zend/tests/gc_042.phpt new file mode 100644 index 0000000000..a7c40fe1ff --- /dev/null +++ b/Zend/tests/gc_042.phpt @@ -0,0 +1,26 @@ +--TEST-- +Object properties HT may need to be removed from nested data +--FILE-- +x = new stdClass; +$t->x->t = $t; +$a = (array) $t->x; +unset($t, $a); +gc_collect_cycles(); +var_dump($x); + +// TODO: The destructor *should* be running here, but doesn't. +// This works in PHP >= 7.3 though. + +?> +--EXPECTF-- +Notice: Undefined variable: x in %s on line %d +NULL diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index d98598cc48..1b6d53a83d 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1007,6 +1007,10 @@ tail_call: ref = Z_COUNTED_P(zv); goto tail_call; } + if (GC_ADDRESS(GC_INFO(ht)) != 0 && GC_REF_GET_COLOR(ht) == GC_BLACK) { + GC_TRACE_REF(ht, "removing from buffer"); + GC_REMOVE_FROM_BUFFER(ht); + } } else { return; } -- cgit v1.2.1