Skip to content

Commit 4f12777

Browse files
committed
Prevent regex cache reuse when JIT flag does not match
1 parent 003cf9d commit 4f12777

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

ext/pcre/php_pcre.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,10 +638,15 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
638638
back the compiled pattern, otherwise go on and compile it. */
639639
zv = zend_hash_find(&PCRE_G(pcre_cache), key);
640640
if (zv) {
641-
if (key != regex) {
642-
zend_string_release_ex(key, 0);
641+
pcre_cache_entry *pce = (pcre_cache_entry*)Z_PTR_P(zv);
642+
if (!(pce->preg_options & PREG_JIT) == !PCRE_G(jit)) {
643+
if (key != regex) {
644+
zend_string_release_ex(key, 0);
645+
}
646+
return pce;
647+
} else {
648+
zend_hash_del(&PCRE_G(pcre_cache), key);
643649
}
644-
return (pcre_cache_entry*)Z_PTR_P(zv);
645650
}
646651

647652
p = ZSTR_VAL(regex);

ext/pcre/tests/gh11374.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-11374 PCRE cache entry cannot be reused when PCRE JIT flag has changed
3+
--SKIPIF--
4+
<?php
5+
if (ini_get("pcre.jit") === false) {
6+
die("skip no jit built");
7+
}
8+
--FILE--
9+
<?php
10+
11+
// testing if PCRE cache entry was reused or not is not possible from userland, so instead we test
12+
// if PCRE JIT flag can be cleared and the pcre_match pass
13+
14+
foreach ([true, false, true] as $pcreJit) {
15+
ini_set('pcre.jit', $pcreJit ? '1' : '0');
16+
var_dump(ini_get('pcre.jit'));
17+
18+
var_dump(preg_match('/^a(b+)/', 'abbc', $matches));
19+
var_dump($matches === ['abb', 'bb']);
20+
}
21+
22+
?>
23+
--EXPECT--
24+
string(1) "1"
25+
int(1)
26+
bool(true)
27+
string(1) "0"
28+
int(1)
29+
bool(true)
30+
string(1) "1"
31+
int(1)
32+
bool(true)

0 commit comments

Comments
 (0)