Skip to content

Commit

Permalink
Fixed second part of the bug #78379 (Cast to object confuses GC, caus…
Browse files Browse the repository at this point in the history
…es crash)
  • Loading branch information
dstogov committed Aug 9, 2019
1 parent 2e2cd65 commit 6b1cc12
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
19 changes: 19 additions & 0 deletions Zend/tests/bug78379_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
Bug #78379.2 (Cast to object confuses GC, causes crash)
--FILE--
<?php
class E {}
function f() {
$e1 = new E;
$e2 = new E;
$a = ['e2' => $e2];
$e1->a = (object)$a;
$e2->e1 = $e1;
$e2->a = (object)$a;
}
f();
gc_collect_cycles();
echo "End\n";
?>
--EXPECT--
End
20 changes: 16 additions & 4 deletions Zend/zend_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,14 @@ static void gc_scan_black(zend_refcounted *ref)
ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n);
end = zv + n;
if (EXPECTED(!ht)) {
if (EXPECTED(!ht) || UNEXPECTED(GC_REF_GET_COLOR(ht) == GC_BLACK)) {
ht = NULL;
if (!n) return;
while (!Z_REFCOUNTED_P(--end)) {
if (zv == end) return;
}
} else {
GC_REF_SET_BLACK(ht);
}
while (zv != end) {
if (Z_REFCOUNTED_P(zv)) {
Expand Down Expand Up @@ -498,11 +501,14 @@ static void gc_mark_grey(zend_refcounted *ref)
ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n);
end = zv + n;
if (EXPECTED(!ht)) {
if (EXPECTED(!ht) || UNEXPECTED(GC_REF_GET_COLOR(ht) == GC_GREY)) {
ht = NULL;
if (!n) return;
while (!Z_REFCOUNTED_P(--end)) {
if (zv == end) return;
}
} else {
GC_REF_SET_COLOR(ht, GC_GREY);
}
while (zv != end) {
if (Z_REFCOUNTED_P(zv)) {
Expand Down Expand Up @@ -616,11 +622,14 @@ static void gc_scan(zend_refcounted *ref)
ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n);
end = zv + n;
if (EXPECTED(!ht)) {
if (EXPECTED(!ht) || UNEXPECTED(GC_REF_GET_COLOR(ht) != GC_GREY)) {
ht = NULL;
if (!n) return;
while (!Z_REFCOUNTED_P(--end)) {
if (zv == end) return;
}
} else {
GC_REF_SET_COLOR(ht, GC_WHITE);
}
while (zv != end) {
if (Z_REFCOUNTED_P(zv)) {
Expand Down Expand Up @@ -791,7 +800,8 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags)
ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n);
end = zv + n;
if (EXPECTED(!ht)) {
if (EXPECTED(!ht) || UNEXPECTED(GC_REF_GET_COLOR(ht) == GC_BLACK)) {
ht = NULL;
if (!n) return count;
while (!Z_REFCOUNTED_P(--end)) {
/* count non-refcounted for compatibility ??? */
Expand All @@ -800,6 +810,8 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags)
}
if (zv == end) return count;
}
} else {
GC_REF_SET_BLACK(ht);
}
while (zv != end) {
if (Z_REFCOUNTED_P(zv)) {
Expand Down

0 comments on commit 6b1cc12

Please sign in to comment.