summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--ext/opcache/Optimizer/block_pass.c5
-rw-r--r--ext/opcache/tests/bug76275.phpt29
-rw-r--r--ext/opcache/zend_file_cache.c4
4 files changed, 41 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 83dcc7cea3..0a9c01eae9 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,10 @@ PHP NEWS
. Fixed bug #76075 --with-fpm-acl wrongly tries to find libacl on FreeBSD.
(mgorny)
+- Opcache:
+ . Fixed bug #76275 (Assertion failure in file cache when unserializing empty
+ try_catch_array). (Nikita)
+
- Reflection:
. Fixed arginfo of array_replace(_recursive) and array_merge(_recursive).
(carusogabriel)
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 84d574a72e..e65ae31803 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -1020,6 +1020,11 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
}
if (i != j) {
op_array->last_try_catch = j;
+ if (j == 0) {
+ efree(op_array->try_catch_array);
+ op_array->try_catch_array = NULL;
+ }
+
if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
zend_op *opline = new_opcodes;
zend_op *end = opline + len;
diff --git a/ext/opcache/tests/bug76275.phpt b/ext/opcache/tests/bug76275.phpt
new file mode 100644
index 0000000000..82e4272185
--- /dev/null
+++ b/ext/opcache/tests/bug76275.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #76275: Assertion failure in file cache when unserializing empty try_catch_array
+--INI--
+opcache.enabled=1
+opcache.enable_cli=1
+opcache.file_cache=/tmp
+--FILE--
+<?php
+
+if (PHP_VERSION_ID >= 70000) {
+ echo "Done";
+ return;
+}
+
+if (!is_callable('random_bytes')) {
+ try {
+ } catch (com_exception $e) {
+ }
+
+ function random_bytes($length)
+ {
+ throw new Exception(
+ 'There is no suitable CSPRNG installed on your system'
+ );
+ return '';
+ }
+}
+--EXPECT--
+Done
diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c
index 8789fb1dde..861a10b3c4 100644
--- a/ext/opcache/zend_file_cache.c
+++ b/ext/opcache/zend_file_cache.c
@@ -96,8 +96,10 @@ static int zend_file_cache_flock(int fd, int type)
#define IS_SERIALIZED_INTERNED(ptr) \
((size_t)(ptr) & Z_UL(1))
+
+/* Allowing == here to account for a potential empty allocation at the end of the memory */
#define IS_SERIALIZED(ptr) \
- ((char*)(ptr) < (char*)script->size)
+ ((char*)(ptr) <= (char*)script->size)
#define IS_UNSERIALIZED(ptr) \
(((char*)(ptr) >= (char*)script->mem && (char*)(ptr) < (char*)script->mem + script->size) || \
IS_ACCEL_INTERNED(ptr))