diff options
| author | Xinchen Hui <laruence@gmail.com> | 2016-03-20 04:55:11 -0700 |
|---|---|---|
| committer | Xinchen Hui <laruence@gmail.com> | 2016-03-20 04:55:11 -0700 |
| commit | 0cacbae4104b04a522cbfb417a8c0c5326d8ca50 (patch) | |
| tree | 97ba6976383e2277cb9a06d23853709e2cff260d | |
| parent | 24f63b1c320cd5d079ba7de40482a9f2067a1c7a (diff) | |
| parent | 9564998e490092fdefa6630944e38692c75e30de (diff) | |
| download | php-git-0cacbae4104b04a522cbfb417a8c0c5326d8ca50.tar.gz | |
Merge branch 'PHP-7.0'
| -rw-r--r-- | Zend/tests/bug71859.phpt | 28 | ||||
| -rw-r--r-- | Zend/zend_objects_API.c | 12 |
2 files changed, 32 insertions, 8 deletions
diff --git a/Zend/tests/bug71859.phpt b/Zend/tests/bug71859.phpt new file mode 100644 index 0000000000..5b62209a1b --- /dev/null +++ b/Zend/tests/bug71859.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #71859 (zend_objects_store_call_destructors operates on realloced memory, crashing) +--FILE-- +<?php +class constructs_in_destructor { + public function __destruct() { + //We are now in zend_objects_store_call_destructors + //This causes a realloc in zend_objects_store_put + for ($i = 0; $i < 10000; ++$i) { + $GLOBALS["a$i"] = new stdClass; + } + //Returns to zend_objects_store_call_destructors, to access freed memory. + } +} + +$a = new constructs_in_destructor; +//Create cycle so destructors are ran only in zend_objects_store_call_destructors +$a->a = $a; + +// Create some objects so zend_objects_store_call_destructors has something +// to do after constructs_in_destructor is destroyed. +for ($i = 0; $i < 200; ++$i) { + $GLOBALS["b$i"] = new stdClass; +} +?> +okey +--EXPECT-- +okey diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 6ca190eabe..00d9425f18 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -44,12 +44,9 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects) ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) { if (objects->top > 1) { - zend_object **obj_ptr = objects->object_buckets + 1; - zend_object **end = objects->object_buckets + objects->top; - - do { - zend_object *obj = *obj_ptr; - + uint32_t i; + for (i = 1; i < objects->top; i++) { + zend_object *obj = objects->object_buckets[i]; if (IS_OBJ_VALID(obj)) { if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; @@ -58,8 +55,7 @@ ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) GC_REFCOUNT(obj)--; } } - obj_ptr++; - } while (obj_ptr != end); + } } } |
