summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-04-27 16:58:30 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-04-27 17:01:35 +0200
commit279ba58edbd0454d7e534e223e3538a2b0b5ff9b (patch)
tree9cf01720da7c3846f0783b749c307b451f48172f
parent2513da4b4c3e7e49bbc01757692056c3e2630145 (diff)
downloadphp-git-279ba58edbd0454d7e534e223e3538a2b0b5ff9b.tar.gz
Fixed bug #76275
* Adjust IS_SERIALIZED() check to account for potential empty allocations at the end of the memory region. * Deallocate empty allocation if all try/catch elements have been removed in the block pass (similar to what we do if all live ranges have been eliminated).
-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 07542c07ca..c9b985012e 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,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 for 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 631798ec1b..81167cea71 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -928,6 +928,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 213028b7a1..23f2f9d0cb 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))