From 368958b3e4ad341da02c901bfd58296d55d91605 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 30 Jan 2017 12:25:50 +0100 Subject: 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. --- ext/opcache/zend_persist.c | 16 ++++++++++++++-- 1 file 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)) { \ -- cgit v1.2.1