summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--Zend/tests/bug76846.phpt27
-rw-r--r--Zend/zend_objects_API.c6
3 files changed, 34 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 8d50dea72f..74dd935014 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.0RC3
+- Core:
+ . Fixed bug #76846 (Segfault in shutdown function after memory limit error).
+ (Nikita)
27 Sep 2018, PHP 7.3.0RC2
diff --git a/Zend/tests/bug76846.phpt b/Zend/tests/bug76846.phpt
new file mode 100644
index 0000000000..c167a8bb78
--- /dev/null
+++ b/Zend/tests/bug76846.phpt
@@ -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
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 038ff25b4a..672a580caa 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -139,8 +139,10 @@ ZEND_API void ZEND_FASTCALL 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++;
}