Skip to content

Commit 4ebf527

Browse files
committed
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fixed handling of references in nested data of objects with destructor
2 parents 7b15299 + 722a44d commit 4ebf527

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
@@ -1344,16 +1344,24 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
13441344
zval *zv;
13451345

13461346
tail_call:
1347-
if (root ||
1348-
(GC_REF_ADDRESS(ref) != 0 &&
1349-
GC_REF_CHECK_COLOR(ref, GC_BLACK))) {
1350-
GC_TRACE_REF(ref, "removing from buffer");
1347+
do {
13511348
if (root) {
1349+
GC_TRACE_REF(ref, "removing from buffer");
13521350
gc_remove_from_roots(root);
13531351
GC_REF_SET_INFO(ref, 0);
13541352
root = NULL;
1355-
} else {
1353+
} else if (GC_REF_ADDRESS(ref) != 0
1354+
&& GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
1355+
GC_TRACE_REF(ref, "removing from buffer");
13561356
GC_REMOVE_FROM_BUFFER(ref);
1357+
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1358+
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1359+
ref = Z_COUNTED(((zend_reference*)ref)->val);
1360+
goto tail_call;
1361+
}
1362+
return;
1363+
} else {
1364+
return;
13571365
}
13581366

13591367
if (GC_TYPE(ref) == IS_OBJECT) {
@@ -1389,12 +1397,6 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
13891397
}
13901398
} else if (GC_TYPE(ref) == IS_ARRAY) {
13911399
ht = (zend_array*)ref;
1392-
} else if (GC_TYPE(ref) == IS_REFERENCE) {
1393-
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
1394-
ref = Z_COUNTED(((zend_reference*)ref)->val);
1395-
goto tail_call;
1396-
}
1397-
return;
13981400
} else {
13991401
return;
14001402
}
@@ -1430,7 +1432,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
14301432
}
14311433
ref = Z_COUNTED_P(zv);
14321434
goto tail_call;
1433-
}
1435+
} while (0);
14341436
}
14351437

14361438
ZEND_API int zend_gc_collect_cycles(void)

0 commit comments

Comments
 (0)