Skip to content

Commit

Permalink
pcre: Workaround bug #81101
Browse files Browse the repository at this point in the history
The way to fix it is to disable certain match start optimizaions. The
observed performance impact appears negligible ATM, compared to the
functional regression revealed.

A possible side effect might occur if a pattern uses (*COMMIT) or
(*MARK), which is however not a very broadly used syntax in PHP. Still
this should be observed and handled by possibly adding a possibility to
reverse PCRE2_NO_START_OPTIMIZE on the user side.

One test shows a behavior change, where instead of int 0 the match
would produce an error and return false. Except strict comparison
is used, this should be acceptable.

Signed-off-by: Anatol Belski <ab@php.net>
(cherry picked from commit d188ca7)
Signed-off-by: Anatol Belski <ab@php.net>
  • Loading branch information
weltling committed Jun 19, 2021
1 parent bc59b04 commit 1a1d86d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ext/pcre/php_pcre.c
Expand Up @@ -570,7 +570,11 @@ static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, ch
PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, int locale_aware)
{
pcre2_code *re = NULL;
#if 10 == PCRE2_MAJOR && 37 == PCRE2_MINOR
uint32_t coptions = PCRE2_NO_START_OPTIMIZE;
#else
uint32_t coptions = 0;
#endif
uint32_t extra_coptions = PHP_PCRE_DEFAULT_EXTRA_COPTIONS;
PCRE2_UCHAR error[128];
PCRE2_SIZE erroffset;
Expand Down
6 changes: 6 additions & 0 deletions ext/pcre/tests/bug75539.phpt
@@ -1,5 +1,11 @@
--TEST--
Bug #75539 - Recursive call errors are not reported by preg_last_error()
--SKIPIF--
<?php
if (10 == PCRE_VERSION_MAJOR && 37 == PCRE_VERSION_MINOR) {
die("skip ");
}
?>
--FILE--
<?php

Expand Down
30 changes: 30 additions & 0 deletions ext/pcre/tests/bug81101.phpt
@@ -0,0 +1,30 @@
--TEST--
Bug #81101 - Invalid single character repetition issues in JIT
--FILE--
<?php

$matches = [];
$test = ' App\Domain\Repository\MetaData\SomethingRepositoryInterface';

preg_match('/\\\\([^\\\\]+)\s*$/', $test, $matches);
var_dump($matches);

$test2 = ' App\Domain\Exception\NotFoundException';

preg_match('/\\\\([^\\\\]+)\s*$/', $test2, $matches);
var_dump($matches);

?>
--EXPECT--
array(2) {
[0]=>
string(29) "\SomethingRepositoryInterface"
[1]=>
string(28) "SomethingRepositoryInterface"
}
array(2) {
[0]=>
string(18) "\NotFoundException"
[1]=>
string(17) "NotFoundException"
}

0 comments on commit 1a1d86d

Please sign in to comment.