Skip to content

Commit 722a44d

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2: Fixed handling of references in nested data of objects with destructor
2 parents 22d23e0 + 9b43e29 commit 722a44d

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

Zend/tests/gc_041.phpt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GC 041: Handling of references in nested data of objects with destructor
3+
--INI--
4+
zend.enable_gc = 1
5+
--FILE--
6+
<?php
7+
class ryat {
8+
var $ryat;
9+
var $chtg;
10+
var $nested;
11+
function __destruct() {
12+
$GLOBALS['x'] = $this;
13+
}
14+
}
15+
$o = new ryat;
16+
$o->nested = [];
17+
$o->nested[] =& $o->nested;
18+
$o->ryat = $o;
19+
$x =& $o->chtg;
20+
unset($o);
21+
gc_collect_cycles();
22+
var_dump($x);
23+
?>
24+
--EXPECT--
25+
object(ryat)#1 (3) {
26+
["ryat"]=>
27+
*RECURSION*
28+
["chtg"]=>
29+
*RECURSION*
30+
["nested"]=>
31+
&array(1) {
32+
[0]=>
33+
*RECURSION*
34+
}
35+
}

Zend/zend_gc.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,16 +1350,24 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
13501350
zval *zv;
13511351

13521352
tail_call:
1353-
if (root ||
1354-
(GC_REF_ADDRESS(ref) != 0 &&
1355-
GC_REF_CHECK_COLOR(ref, GC_BLACK))) {
1356-
GC_TRACE_REF(ref, "removing from buffer");
1353+
do {
13571354
if (root) {
1355+
GC_TRACE_REF(ref, "removing from buffer");
13581356
gc_remove_from_roots(root);
13591357
GC_REF_SET_INFO(ref, 0);
13601358
root = NULL;
1361-
} else {
1359+
} else if (GC_REF_ADDRESS(ref) != 0
1360+
&& GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
1361+
GC_TRACE_REF(ref, "removing from buffer");
13621362
GC_REMOVE_FROM_BUFFER(ref);
1363+
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1364+
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1365+
ref = Z_COUNTED(((zend_reference*)ref)->val);
1366+
goto tail_call;
1367+
}
1368+
return;
1369+
} else {
1370+
return;
13631371
}
13641372

13651373
if (GC_TYPE(ref) == IS_OBJECT) {
@@ -1397,12 +1405,6 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
13971405
}
13981406
} else if (GC_TYPE(ref) == IS_ARRAY) {
13991407
ht = (zend_array*)ref;
1400-
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1401-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1402-
ref = Z_COUNTED(((zend_reference*)ref)->val);
1403-
goto tail_call;
1404-
}
1405-
return;
14061408
} else {
14071409
return;
14081410
}
@@ -1438,7 +1440,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
14381440
}
14391441
ref = Z_COUNTED_P(zv);
14401442
goto tail_call;
1441-
}
1443+
} while (0);
14421444
}
14431445

14441446
ZEND_API int zend_gc_collect_cycles(void)

0 commit comments

Comments
 (0)