]> granicus.if.org Git - php/commitdiff
Make PCRE cache per-request on CLI
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 25 Mar 2019 14:46:43 +0000 (15:46 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 26 Mar 2019 09:10:41 +0000 (10:10 +0100)
There will only be one request on the CLI SAPI, so there is no
advantage to having a persistent PCRE cache. Using a non-persistent
cache allows us to use arbitrary strings as cache keys.

ext/opcache/ZendAccelerator.c
ext/pcre/php_pcre.c
ext/pcre/php_pcre.h

index 73fd894154ecd1a5e8e9178a2aee38cb18e7f39e..7c71e1d5ef829bbdd452569191a286d61e567ab7 100644 (file)
@@ -2261,6 +2261,10 @@ static void accel_reset_pcre_cache(void)
 {
        Bucket *p;
 
+       if (PCRE_G(per_request_cache)) {
+               return;
+       }
+
        ZEND_HASH_FOREACH_BUCKET(&PCRE_G(pcre_cache), p) {
                /* Remove PCRE cache entries with inconsistent keys */
                if (zend_accel_in_shm(p->key)) {
index fe79360f9a8128d266c5078ba5e236f8a23efeaf..a132e7f6116cff628796e3c0ca22ed72899d0cca 100644 (file)
@@ -23,6 +23,7 @@
 #include "ext/standard/info.h"
 #include "ext/standard/basic_functions.h"
 #include "zend_smart_str.h"
+#include "SAPI.h"
 
 #include "ext/standard/php_string.h"
 
@@ -144,7 +145,7 @@ static void php_free_pcre_cache(zval *data) /* {{{ */
        pcre_cache_entry *pce = (pcre_cache_entry *) Z_PTR_P(data);
        if (!pce) return;
        pcre2_code_free(pce->re);
-       pefree(pce, 1);
+       pefree(pce, !PCRE_G(per_request_cache));
 }
 /* }}} */
 
@@ -253,7 +254,13 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
 {
        php_pcre_mutex_alloc();
 
-       zend_hash_init(&pcre_globals->pcre_cache, 0, NULL, php_free_pcre_cache, 1);
+       /* If we're on the CLI SAPI, there will only be one request, so we don't need the
+        * cache to survive after RSHUTDOWN. */
+       pcre_globals->per_request_cache = strcmp(sapi_module.name, "cli") == 0;
+       if (!pcre_globals->per_request_cache) {
+               zend_hash_init(&pcre_globals->pcre_cache, 0, NULL, php_free_pcre_cache, 1);
+       }
+
        pcre_globals->backtrack_limit = 0;
        pcre_globals->recursion_limit = 0;
        pcre_globals->error_code      = PHP_PCRE_NO_ERROR;
@@ -272,7 +279,9 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
 
 static PHP_GSHUTDOWN_FUNCTION(pcre) /* {{{ */
 {
-       zend_hash_destroy(&pcre_globals->pcre_cache);
+       if (!pcre_globals->per_request_cache) {
+               zend_hash_destroy(&pcre_globals->pcre_cache);
+       }
 
        php_pcre_shutdown_pcre2();
 #if HAVE_SETLOCALE
@@ -438,10 +447,10 @@ static PHP_MSHUTDOWN_FUNCTION(pcre)
 }
 /* }}} */
 
-#ifdef HAVE_PCRE_JIT_SUPPORT
 /* {{{ PHP_RINIT_FUNCTION(pcre) */
 static PHP_RINIT_FUNCTION(pcre)
 {
+#ifdef HAVE_PCRE_JIT_SUPPORT
        if (UNEXPECTED(!pcre2_init_ok)) {
                /* Retry. */
                php_pcre_mutex_lock();
@@ -454,14 +463,22 @@ static PHP_RINIT_FUNCTION(pcre)
        }
 
        mdata_used = 0;
+#endif
+
+       if (PCRE_G(per_request_cache)) {
+               zend_hash_init(&PCRE_G(pcre_cache), 0, NULL, php_free_pcre_cache, 0);
+       }
 
        return SUCCESS;
 }
 /* }}} */
-#endif
 
 static PHP_RSHUTDOWN_FUNCTION(pcre)
 {
+       if (PCRE_G(per_request_cache)) {
+               zend_hash_destroy(&PCRE_G(pcre_cache));
+       }
+
        zval_ptr_dtor(&PCRE_G(unmatched_null_pair));
        zval_ptr_dtor(&PCRE_G(unmatched_empty_pair));
        ZVAL_UNDEF(&PCRE_G(unmatched_null_pair));
@@ -859,22 +876,22 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex)
         * as hash keys especually for this table.
         * See bug #63180
         */
-       if (!(GC_FLAGS(key) & IS_STR_PERMANENT)) {
+       if (!(GC_FLAGS(key) & IS_STR_PERMANENT) && !PCRE_G(per_request_cache)) {
                zend_string *str = zend_string_init(ZSTR_VAL(key), ZSTR_LEN(key), 1);
-
                GC_MAKE_PERSISTENT_LOCAL(str);
 
-#if HAVE_SETLOCALE
-               if (key != regex) {
-                       zend_string_release_ex(key, 0);
-               }
-#endif
                ret = zend_hash_add_new_mem(&PCRE_G(pcre_cache), str, &new_entry, sizeof(pcre_cache_entry));
                zend_string_release(str);
        } else {
                ret = zend_hash_add_new_mem(&PCRE_G(pcre_cache), key, &new_entry, sizeof(pcre_cache_entry));
        }
 
+#if HAVE_SETLOCALE
+       if (key != regex) {
+               zend_string_release_ex(key, 0);
+       }
+#endif
+
        return ret;
 }
 /* }}} */
@@ -3023,11 +3040,7 @@ zend_module_entry pcre_module_entry = {
        pcre_functions,
        PHP_MINIT(pcre),
        PHP_MSHUTDOWN(pcre),
-#ifdef HAVE_PCRE_JIT_SUPPORT
        PHP_RINIT(pcre),
-#else
-       NULL,
-#endif
        PHP_RSHUTDOWN(pcre),
        PHP_MINFO(pcre),
        PHP_PCRE_VERSION,
index ba38a26a08ab8ed12e965954bb2217ab2e083726..b59f16e89803b8ec0a46a1339cc7ad335a2a04da 100644 (file)
@@ -72,6 +72,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pcre)
 #ifdef HAVE_PCRE_JIT_SUPPORT
        zend_bool jit;
 #endif
+       zend_bool per_request_cache;
        int  error_code;
        /* Used for unmatched subpatterns in OFFSET_CAPTURE mode */
        zval unmatched_null_pair;