Skip to content

Commit 589542f

Browse files
committed
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.
1 parent 1e82a2d commit 589542f

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

Zend/tests/gc_042.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Object properties HT may need to be removed from nested data
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public function __destruct() {
8+
$GLOBALS['x'] = $this;
9+
}
10+
}
11+
12+
$t = new Test;
13+
$t->x = new stdClass;
14+
$t->x->t = $t;
15+
$a = (array) $t->x;
16+
unset($t, $a);
17+
gc_collect_cycles();
18+
var_dump($x);
19+
20+
// TODO: The destructor *should* be running here, but doesn't.
21+
// This works in PHP >= 7.3 though.
22+
23+
?>
24+
--EXPECTF--
25+
Notice: Undefined variable: x in %s on line %d
26+
NULL

Zend/zend_gc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,10 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
10071007
ref = Z_COUNTED_P(zv);
10081008
goto tail_call;
10091009
}
1010+
if (GC_ADDRESS(GC_INFO(ht)) != 0 && GC_REF_GET_COLOR(ht) == GC_BLACK) {
1011+
GC_TRACE_REF(ht, "removing from buffer");
1012+
GC_REMOVE_FROM_BUFFER(ht);
1013+
}
10101014
} else {
10111015
return;
10121016
}

0 commit comments

Comments
 (0)