pcre: Workaround bug #81101

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 d188ca7688)
Signed-off-by: Anatol Belski <ab@php.net>
This commit is contained in:
Anatol Belski 2021-06-06 17:46:59 +02:00
parent ed431ea2f6
commit f7ab7951f1
No known key found for this signature in database
GPG Key ID: BCAA30EA9C0D5763
3 changed files with 40 additions and 0 deletions

View File

@ -595,7 +595,11 @@ static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, co
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
PCRE2_UCHAR error[128];
PCRE2_SIZE erroffset;
int errnumber;

View File

@ -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

View File

@ -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"
}