Skip to content

Commit

Permalink
Merge branch 'PHP-7.3' into PHP-7.4
Browse files Browse the repository at this point in the history
* PHP-7.3:
  Fixed handling of references in nested data of objects with destructor
  • Loading branch information
dstogov committed Aug 9, 2019
2 parents 7b15299 + 722a44d commit 4ebf527
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 12 deletions.
35 changes: 35 additions & 0 deletions Zend/tests/gc_041.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
GC 041: Handling of references in nested data of objects with destructor
--INI--
zend.enable_gc = 1
--FILE--
<?php
class ryat {
var $ryat;
var $chtg;
var $nested;
function __destruct() {
$GLOBALS['x'] = $this;
}
}
$o = new ryat;
$o->nested = [];
$o->nested[] =& $o->nested;
$o->ryat = $o;
$x =& $o->chtg;
unset($o);
gc_collect_cycles();
var_dump($x);
?>
--EXPECT--
object(ryat)#1 (3) {
["ryat"]=>
*RECURSION*
["chtg"]=>
*RECURSION*
["nested"]=>
&array(1) {
[0]=>
*RECURSION*
}
}
26 changes: 14 additions & 12 deletions Zend/zend_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1344,16 +1344,24 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
zval *zv;

tail_call:
if (root ||
(GC_REF_ADDRESS(ref) != 0 &&
GC_REF_CHECK_COLOR(ref, GC_BLACK))) {
GC_TRACE_REF(ref, "removing from buffer");
do {
if (root) {
GC_TRACE_REF(ref, "removing from buffer");
gc_remove_from_roots(root);
GC_REF_SET_INFO(ref, 0);
root = NULL;
} else {
} else if (GC_REF_ADDRESS(ref) != 0
&& GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
GC_TRACE_REF(ref, "removing from buffer");
GC_REMOVE_FROM_BUFFER(ref);
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
ref = Z_COUNTED(((zend_reference*)ref)->val);
goto tail_call;
}
return;
} else {
return;
}

if (GC_TYPE(ref) == IS_OBJECT) {
Expand Down Expand Up @@ -1389,12 +1397,6 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
}
} else if (GC_TYPE(ref) == IS_ARRAY) {
ht = (zend_array*)ref;
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
ref = Z_COUNTED(((zend_reference*)ref)->val);
goto tail_call;
}
return;
} else {
return;
}
Expand Down Expand Up @@ -1430,7 +1432,7 @@ static void gc_remove_nested_data_from_buffer(zend_refcounted *ref, gc_root_buff
}
ref = Z_COUNTED_P(zv);
goto tail_call;
}
} while (0);
}

ZEND_API int zend_gc_collect_cycles(void)
Expand Down

0 comments on commit 4ebf527

Please sign in to comment.