- Core:
. Added ability to disable huge pages in Zend Memory Manager through
the environment variable USE_ZEND_ALLOC_HUGE_PAGES=0. (Dmitry)
+ . Fixed Bug #71859 (zend_objects_store_call_destructors operates on realloced
+ memory, crashing). (Laruence)
. Fixed bug #71841 (EG(error_zval) is not handled well). (Laruence)
- ODBC:
--- /dev/null
+--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
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;
GC_REFCOUNT(obj)--;
}
}
- obj_ptr++;
- } while (obj_ptr != end);
+ }
}
}