summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2017-12-06 15:59:21 +0100
committerAnatol Belski <ab@php.net>2017-12-06 15:59:21 +0100
commit1b29dc0b1c4836085a17cbf2f59dae8aeb85424c (patch)
tree74c7db869395e148c90a35d5bbaa6a4e56a2e1cd
parent092fd44474676857359153c859e0cb300720d80a (diff)
downloadphp-git-1b29dc0b1c4836085a17cbf2f59dae8aeb85424c.tar.gz
Fix yet one data race in PCRE
PCRE 8.x initializes the pattern compiler on demand during the first pcre_study call. It could be worse, but since the compiled patterns are cached, the locking impact is minimal. PCRE 10.x always compiles the pattern and thread sanitizer doesn't complain about the compiler initialization, thus the newer PCRE version seems to be unafected.
-rw-r--r--ext/pcre/php_pcre.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index a743f30b04..bf8e02c54b 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -67,7 +67,7 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre)
#define PCRE_JIT_STACK_MAX_SIZE (64 * 1024)
ZEND_TLS pcre_jit_stack *jit_stack = NULL;
#endif
-#if defined(ZTS) && defined(HAVE_PCRE_JIT_SUPPORT)
+#if defined(ZTS)
static MUTEX_T pcre_mt = NULL;
#define php_pcre_mutex_alloc() if (!pcre_mt) pcre_mt = tsrm_mutex_alloc();
#define php_pcre_mutex_free() if (pcre_mt) tsrm_mutex_free(pcre_mt); pcre_mt = NULL;
@@ -538,7 +538,9 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex)
/* If study option was specified, study the pattern and
store the result in extra for passing to pcre_exec. */
if (do_study) {
+ php_pcre_mutex_lock();
extra = pcre_study(re, soptions, &error);
+ php_pcre_mutex_unlock();
if (extra) {
extra->flags |= PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION;
extra->match_limit = (unsigned long)PCRE_G(backtrack_limit);