summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2017-01-30 12:25:50 +0100
committerAnatol Belski <ab@php.net>2017-01-30 12:44:21 +0100
commit368958b3e4ad341da02c901bfd58296d55d91605 (patch)
tree09c65c24d5b58c836d2fd127ea1598658f0d9ed4
parentdd227c2b23325fb7df524a3bc06c050e41b9d252 (diff)
downloadphp-git-368958b3e4ad341da02c901bfd58296d55d91605.tar.gz
Fixed bug #73983 crash on finish work with phar in cli + opcache
The file_cache_only option causes the storage to be per process, furthermore the arena is destroyed per request. Thus, zend_string's can't survive between request and the permanent flag should not be set. This is already done with the file cache part, but the persistency part is used in various scenarios and should respect this case as well. In this particular bug, the pcre pattern cache needs to survive between requests and uses pattern strings as hash keys. One more case relevant here would be various situations where the flow disables the use of shared memory.
-rw-r--r--ext/opcache/zend_persist.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index 52cdb0a96d..eca90b30ef 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -33,6 +33,18 @@
#define zend_accel_memdup(p, size) \
_zend_shared_memdup((void*)p, size, 0)
+#ifdef HAVE_OPCACHE_FILE_CACHE
+#define zend_set_str_gc_flags(str) do { \
+ if (ZCG(accel_directives).file_cache_only) { \
+ GC_FLAGS(str) = IS_STR_INTERNED; \
+ } else { \
+ GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \
+ } \
+} while (0)
+#else
+#define zend_set_str_gc_flags(str) GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT
+#endif
+
#define zend_accel_store_string(str) do { \
zend_string *new_str = zend_shared_alloc_get_xlat_entry(str); \
if (new_str) { \
@@ -43,13 +55,13 @@
zend_string_release(str); \
str = new_str; \
zend_string_hash_val(str); \
- GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \
+ zend_set_str_gc_flags(str); \
} \
} while (0)
#define zend_accel_memdup_string(str) do { \
str = zend_accel_memdup(str, _ZSTR_STRUCT_SIZE(ZSTR_LEN(str))); \
zend_string_hash_val(str); \
- GC_FLAGS(str) = IS_STR_INTERNED | IS_STR_PERMANENT; \
+ zend_set_str_gc_flags(str); \
} while (0)
#define zend_accel_store_interned_string(str) do { \
if (!IS_ACCEL_INTERNED(str)) { \