]> granicus.if.org Git - php/commitdiff
Fixed bug #76846
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 28 Sep 2018 10:56:47 +0000 (12:56 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 28 Sep 2018 10:56:47 +0000 (12:56 +0200)
NEWS
Zend/tests/bug76846.phpt [new file with mode: 0644]
Zend/zend_objects_API.c

diff --git a/NEWS b/NEWS
index 00ee93ea437770ec75c0b6dbc6f5f103996302fe..65fe90403a1942890c8a0c57b259b8fd114a7938 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP                                                                        NEWS
 - Core:
   . Fixed bug #76901 (method_exists on SPL iterator passthrough method corrupts
     memory). (Nikita)
+  . Fixed bug #76846 (Segfault in shutdown function after memory limit error).
+    (Nikita)
 
 - CURL:
   . Fixed bug #76480 (Use curl_multi_wait() so that timeouts are respected).
diff --git a/Zend/tests/bug76846.phpt b/Zend/tests/bug76846.phpt
new file mode 100644 (file)
index 0000000..c167a8b
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #76846: Segfault in shutdown function after memory limit error
+--INI--
+memory_limit=33M
+--SKIPIF--
+<?php
+$zend_mm_enabled = getenv("USE_ZEND_ALLOC");
+if ($zend_mm_enabled === "0") {
+       die("skip Zend MM disabled");
+}
+?>
+--FILE--
+<?php
+
+register_shutdown_function(function() {
+    new stdClass;
+});
+
+$ary = [];
+while (true) {
+    $ary[] = new stdClass;
+}
+
+?>
+--EXPECTF--
+Fatal error: Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes) in %s on line %d
+%A
index 54d8d51456d81262faab294c3bbece165c707309..cbb637c54907e10aba353e869cbc2fdb972fb3ef 100644 (file)
@@ -116,8 +116,10 @@ ZEND_API void zend_objects_store_put(zend_object *object)
                EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
        } else {
                if (EG(objects_store).top == EG(objects_store).size) {
-                       EG(objects_store).size <<= 1;
-                       EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, EG(objects_store).size * sizeof(zend_object*));
+                       uint32_t new_size = 2 * EG(objects_store).size;
+                       EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*));
+                       /* Assign size after realloc, in case it fails */
+                       EG(objects_store).size = new_size;
                }
                handle = EG(objects_store).top++;
        }