PCRE2_EXTRA_CASELESS_RESTRICT is only available as of pcre2 10.43.
Note: no check is necessary for pcre2_set_compile_extra_options because
it is available since pcre2 10.30, which is the minimum version PHP
requires.
Adds support for "Caseless restricted" matching added in PCRE2lib
10.43 with the "r" modifier.
This is `PCRE2_EXTRA_CASELESS_RESTRICT` in PCRE2. This is an "extra"
option, which means it is not possible to pass this option as
pcre2_compile() function parameter.
This option is passed in a pcre2_set_compile_extra_options() call.
Previously, these extra options are set at php_pcre_init_pcre2(),
but after this change, it is possible to customize the options
by adding bits to `eoptions` in pcre_get_compiled_regex_cache_ex().
The tests for this change are ported from upstream test suite[^1].
[^1]: c13d54f658 (diff-8c8312e4eb2d35bb16485404b7b5cc0eaef0bca1aa95ff5febf6a1890048305c)
The code in the attached test used to work correctly in PHP 8.0, but not
in 8.1+. This is because PHP 8.1+ uses a more modern version of pcre2
than PHP 8.0, and that pcre2 versions has a regression.
While upgrading pcre2lib seems to be only done for the master branch, it
is possible to backport upstream fixes to stable branches. This has been
already done in the past in for JIT regressions [1], so it is not
unprecedented.
We backport the upstream pcre2 fix [2].
[1] 788a701e22
[2] https://github.com/PCRE2Project/pcre2/pull/135
Closes GH-12108.
The ZVAL_ARR macro always set the zval type_info to IS_ARRAY_EX, even if the
hash table is immutable. Since in preg_replace_callback_array() we can return
the passed array directly, and that passed array can be immutable, we need to
reset the type_flags to keep the VM from performing ref-counting on the array.
Fixes GH-10968
Closes GH-10970
In 8b3c1a3, this was disallowed to fix#55856, which was a security
issue caused by the /e modifier. The fix that was made was the
"Easier fix" as described in the original report.
With this fix, pattern strings are no longer treated as null terminated,
so null characters can be placed inside and matched against with regex
patterns without security problems, so there is no longer a reason to
give the error. Allowing this is consistent with the behaviour of many
other languages, including JavaScript, and thanks to PCRE2[0], it does
not require manually escaping null characters. Now that we can avoid the
error here without the cost of escaping characters, there is really no
need anymore to stray here from the conventional behaviour.
Currently, null characters are still disallowed before the first
delimiter and in the options section at the end of a regex string, but
these error messages have been updated.
[0] Since PCRE2, pattern strings no longer have to be null terminated,
and raw null characters match as normal.
Closes GH-8114.
We backport the respective upstream fix[1] to our bundled pcre2lib plus
the follow-up fix[2] for a functional regression.
[1] <dc5f966635>
[2] <e7af7efaa1>
Closes GH-7573.
Trimming a potentially over-allocated string appears to be reasonable,
so we drop the condition altogether.
We also re-allocate twice the size needed in the first place, and not
roughly tripple the size.
Closes GH-7231.
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>
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>
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>
The compile context is shared between patterns, so we need to set
the character tables unconditionally in case we switched from
a non-C locale to the C locale.
Create a separate general context that uses ZMM as allocator and
use it to allocate temporary PCRE match data (there is still one
global match data). There is no requirement that the match data
and the compiled regex / match context use the same general context.
This makes sure that we do not leak persistent memory on bailout
and fixes oss-fuzz #25296, on which half the libfuzzer runs
currently get stuck.