1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fixed bug #76427 (Segfault in zend_objects_store_put)

This commit is contained in:
Xinchen Hui
2018-06-11 21:00:09 +08:00
parent eebad01672
commit ffaee27478
6 changed files with 33 additions and 7 deletions

1
NEWS
View File

@@ -3,6 +3,7 @@ PHP NEWS
?? ??? ????, PHP 7.3.0alpha2
- Core:
. Fixed bug #76427 (Segfault in zend_objects_store_put). (Laruence)
. Fixed bug #76422 (ftruncate fails on files > 2GB). (Anatol)
- EXIF:

View File

@@ -0,0 +1,24 @@
--TEST--
Bug #76427 (Segfault in zend_objects_store_put)
--FILE--
<?php
$func = function () {
yield 2;
};
$a = new stdclass();
$b = new stdclass();
$a->b = $b;
$b->a = $a;
$func = $a->func = $func();
unset($b);
unset($a);
unset($func);
var_dump(gc_collect_cycles());
?>
--EXPECT--
int(4)

View File

@@ -1401,8 +1401,8 @@ ZEND_API int zend_gc_collect_cycles(void)
GC_DELREF(obj);
}
}
SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[obj->handle], EG(objects_store).free_list_head);
EG(objects_store).free_list_head = obj->handle;
ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle);
current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
} else if (GC_TYPE(p) == IS_ARRAY) {
zend_array *arr = (zend_array*)p;

View File

@@ -145,7 +145,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
}
/* Free closure object */
if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
if ((EX_CALL_INFO() & ZEND_CALL_CLOSURE) &&
EXPECTED(GC_TYPE(ZEND_CLOSURE_OBJECT(EX(func))) == IS_OBJECT)) {
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
}

View File

@@ -150,10 +150,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
EG(objects_store).object_buckets[handle] = object;
}
#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle) \
SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle], EG(objects_store).free_list_head); \
EG(objects_store).free_list_head = handle;
ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */
{
/* Make sure we hold a reference count during the destructor call

View File

@@ -37,6 +37,10 @@
(o) = (zend_object*)((((zend_uintptr_t)(n)) << 1) | OBJ_BUCKET_INVALID); \
} while (0)
#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(h) do { \
SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[(h)], EG(objects_store).free_list_head); \
EG(objects_store).free_list_head = (h); \
} while (0)
#define OBJ_RELEASE(obj) zend_object_release(obj)