diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 4c63ab0920ae..393315554861 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -369,10 +369,6 @@ static char *_pcre2_config_str(uint32_t what) /* {{{ PHP_MINFO_FUNCTION(pcre) */ static PHP_MINFO_FUNCTION(pcre) { -#ifdef HAVE_PCRE_JIT_SUPPORT - uint32_t flag = 0; - char *jit_target = _pcre2_config_str(PCRE2_CONFIG_JITTARGET); -#endif char *version = _pcre2_config_str(PCRE2_CONFIG_VERSION); char *unicode = _pcre2_config_str(PCRE2_CONFIG_UNICODE_VERSION); @@ -384,6 +380,8 @@ static PHP_MINFO_FUNCTION(pcre) free(unicode); #ifdef HAVE_PCRE_JIT_SUPPORT + uint32_t flag = 0; + char *jit_target = _pcre2_config_str(PCRE2_CONFIG_JITTARGET); if (!pcre2_config(PCRE2_CONFIG_JIT, &flag)) { php_info_print_table_row(2, "PCRE JIT Support", flag ? "enabled" : "disabled"); } else { @@ -579,7 +577,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo #else uint32_t coptions = 0; #endif +#if PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 45 + uint32_t eoptions = PCRE2_EXTRA_NEVER_CALLOUT; +#else uint32_t eoptions = 0; +#endif PCRE2_UCHAR error[128]; PCRE2_SIZE erroffset; int errnumber; @@ -710,7 +712,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* PCRE specific options */ case 'A': coptions |= PCRE2_ANCHORED; break; case 'D': coptions |= PCRE2_DOLLAR_ENDONLY;break; -#ifdef PCRE2_EXTRA_CASELESS_RESTRICT +#ifdef PCRE2_EXTRA_CASELESS_RESTRICT /* Added in 10.43 (16-February-2024) */ case 'r': eoptions |= PCRE2_EXTRA_CASELESS_RESTRICT; break; #endif case 'S': /* Pass. */ break; @@ -720,9 +722,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII characters, even in UTF-8 mode. However, this can be changed by setting the PCRE2_UCP option. */ -#ifdef PCRE2_UCP coptions |= PCRE2_UCP; -#endif /* The \C escape sequence is unsafe in PCRE2_UTF mode */ coptions |= PCRE2_NEVER_BACKSLASH_C; break; @@ -781,10 +781,15 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo zend_string_release_ex(key, 0); } const char *err_msg = (const char*) error; - if (errnumber == PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED) { - err_msg = "using \\C is incompatible with the 'u' modifier"; - } else { - pcre2_get_error_message(errnumber, error, sizeof(error)); + switch (errnumber) { + case PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND: + err_msg = "\\K is not allowed in lookarounds"; + break; + case PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED: + err_msg = "using \\C is incompatible with the 'u' modifier"; + break; + default: + pcre2_get_error_message(errnumber, error, sizeof(error)); } php_error_docref(NULL,E_WARNING, "Compilation failed: %s at offset %zu", err_msg, erroffset); pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); diff --git a/ext/pcre/tests/bug70345.phpt b/ext/pcre/tests/bug70345.phpt index bdfa2041fc08..eee101a10e0e 100644 --- a/ext/pcre/tests/bug70345.phpt +++ b/ext/pcre/tests/bug70345.phpt @@ -19,8 +19,8 @@ preg_match($regex, $subject, $matches); var_dump($matches); ?> --EXPECTF-- -Warning: preg_split(): Compilation failed: \K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) at offset 9 in %s on line %d +Warning: preg_split(): Compilation failed: \K is not allowed in lookarounds at offset 9 in %s on line %d bool(false) -Warning: preg_match(): Compilation failed: \K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) at offset 12 in %s on line %d +Warning: preg_match(): Compilation failed: \K is not allowed in lookarounds at offset 12 in %s on line %d NULL diff --git a/ext/pcre/tests/bug75457.phpt b/ext/pcre/tests/bug75457.phpt index 1401b25ff6fb..97adb7c66e92 100644 --- a/ext/pcre/tests/bug75457.phpt +++ b/ext/pcre/tests/bug75457.phpt @@ -1,5 +1,11 @@ --TEST-- Bug #75457 (heap-use-after-free in php7.0.25) +--SKIPIF-- += 10 && PCRE_VERSION_MINOR >= 45) { + die("skip callout feature is disable in PCRE2 10.45 and above"); +} +?> --FILE-- = 10 && PCRE_VERSION_MINOR >= 45) { + die("skip callout feature is disable in PCRE2 10.45 and above"); +} +?> +--FILE-- + +--EXPECT-- +int(0) diff --git a/ext/pcre/tests/callout_syntax_in_pattern_disabled.phpt b/ext/pcre/tests/callout_syntax_in_pattern_disabled.phpt new file mode 100644 index 000000000000..d60e90bf7c5d --- /dev/null +++ b/ext/pcre/tests/callout_syntax_in_pattern_disabled.phpt @@ -0,0 +1,20 @@ +--TEST-- +PCRE2 callout feature is not supported and disabled if pcre2 lib permits it. +--SKIPIF-- += 10 && PCRE_VERSION_MINOR >= 45)) { + die("skip needs 10.45 or above"); +} +?> +--FILE-- + +--EXPECTF-- +Warning: preg_match(): Compilation failed: using callouts is disabled by the application at offset 4 in %s on line %d +bool(false) diff --git a/ext/pcre/tests/disabled_pcre_compile_options.phpt b/ext/pcre/tests/disabled_pcre_compile_options.phpt new file mode 100644 index 000000000000..c675ac7b6117 --- /dev/null +++ b/ext/pcre/tests/disabled_pcre_compile_options.phpt @@ -0,0 +1,25 @@ +--TEST-- +Disabled PCRE2 regex compilation features. +--FILE-- + +--EXPECTF-- +Warning: preg_match(): Compilation failed: PCRE2 does not support \F, \L, \l, \N{name}, \U, or \u at offset 2 in %s on line %d +bool(false) + +Warning: preg_match(): Compilation failed: using \C is incompatible with the 'u' modifier at offset 2 in %s on line %d +bool(false) + +Warning: preg_match(): Compilation failed: \K is not allowed in lookarounds at offset 8 in %s on line %d +bool(false) diff --git a/ext/pcre/tests/preg_grep_error1.phpt b/ext/pcre/tests/preg_grep_error1.phpt index 0c1a4733ca90..2629f5aa52d3 100644 --- a/ext/pcre/tests/preg_grep_error1.phpt +++ b/ext/pcre/tests/preg_grep_error1.phpt @@ -13,26 +13,11 @@ $values = [ '/[a-zA-Z]', //Regex without closing delimiter '[a-zA-Z]/', //Regex without opening delimiter '/[a-zA-Z]/F', - [ - '[a-z]', //Array of Regexes - '[A-Z]', - '[0-9]', - ], '/[a-zA-Z]/', //Regex string ]; $array = [123, 'abc', 'test']; foreach ($values as $value) { - try { - var_dump(preg_grep($value, $array)); - } catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; - } -} -$value = new stdclass(); //Object -try { var_dump(preg_grep($value, $array)); -} catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- @@ -47,11 +32,9 @@ bool(false) Warning: preg_grep(): Unknown modifier 'F' in %spreg_grep_error1.php on line %d bool(false) -TypeError: preg_grep(): Argument #1 ($pattern) must be of type string, array given array(2) { [1]=> string(3) "abc" [2]=> string(4) "test" } -TypeError: preg_grep(): Argument #1 ($pattern) must be of type string, stdClass given diff --git a/ext/pcre/tests/preg_match_all_error1.phpt b/ext/pcre/tests/preg_match_all_error1.phpt index 4965cc1913bb..d2d212fc6c46 100644 --- a/ext/pcre/tests/preg_match_all_error1.phpt +++ b/ext/pcre/tests/preg_match_all_error1.phpt @@ -13,29 +13,14 @@ $regex_array = [ '/[a-zA-Z]', //Regex without closing delimiter '[a-zA-Z]/', //Regex without opening delimiter '/[a-zA-Z]/F', - [ - '[a-z]', //Array of Regexes - '[A-Z]', - '[0-9]', - ], '/[a-zA-Z]/', //Regex string ]; $subject = 'test'; foreach ($regex_array as $regex_value) { - try { - var_dump(preg_match_all($regex_value, $subject, $matches1)); - } catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; - } + var_dump(preg_match_all($regex_value, $subject, $matches1)); var_dump($matches1); } -$regex_value = new stdclass(); //Object -try { - var_dump(preg_match_all($regex_value, $subject, $matches)); -} catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; -} -var_dump($matches); + ?> --EXPECTF-- Warning: preg_match_all(): Delimiter must not be alphanumeric, backslash, or NUL byte in %spreg_match_all_error1.php on line %d @@ -53,8 +38,6 @@ NULL Warning: preg_match_all(): Unknown modifier 'F' in %spreg_match_all_error1.php on line %d bool(false) NULL -TypeError: preg_match_all(): Argument #1 ($pattern) must be of type string, array given -NULL int(4) array(1) { [0]=> @@ -69,5 +52,3 @@ array(1) { string(1) "t" } } -TypeError: preg_match_all(): Argument #1 ($pattern) must be of type string, stdClass given -NULL diff --git a/ext/pcre/tests/preg_replace_error1.phpt b/ext/pcre/tests/preg_replace_error1.phpt index 5219496a5535..ff19998d8c5a 100644 --- a/ext/pcre/tests/preg_replace_error1.phpt +++ b/ext/pcre/tests/preg_replace_error1.phpt @@ -25,12 +25,6 @@ $subject = 'a'; foreach ($regex_array as $regex_value) { var_dump(preg_replace($regex_value, $replace, $subject)); } -$regex_value = new stdclass(); //Object -try { - var_dump(preg_replace($regex_value, $replace, $subject)); -} catch (Error $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; -} ?> --EXPECTF-- Warning: preg_replace(): Delimiter must not be alphanumeric, backslash, or NUL byte in %spreg_replace_error1.php on line %d @@ -46,4 +40,3 @@ Warning: preg_replace(): Unknown modifier 'F' in %spreg_replace_error1.php on li NULL string(1) "a" string(1) "1" -TypeError: preg_replace(): Argument #1 ($pattern) must be of type array|string, stdClass given diff --git a/ext/pcre/tests/preg_replace_error2.phpt b/ext/pcre/tests/preg_replace_error2.phpt index 6b4a1bfae934..d007a6c9946d 100644 --- a/ext/pcre/tests/preg_replace_error2.phpt +++ b/ext/pcre/tests/preg_replace_error2.phpt @@ -9,7 +9,10 @@ Test preg_replace() function : error conditions - wrong arg types * Testing how preg_replace reacts to being passed the wrong type of replacement argument */ $regex = '/[a-zA-Z]/'; -$replace = array('this is a string', array('this is', 'a subarray'),); +$replace = [ + 'this is a string', + ['this is', 'a subarray'], +]; $subject = 'test'; foreach($replace as $value) { try { @@ -18,14 +21,7 @@ foreach($replace as $value) { echo $e::class, ': ', $e->getMessage(), "\n"; } } -$value = new stdclass(); //Object -try { - var_dump(preg_replace($regex, $value, $subject)); -} catch (Error $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; -} ?> --EXPECT-- string(64) "this is a stringthis is a stringthis is a stringthis is a string" TypeError: preg_replace(): Argument #1 ($pattern) must be of type array when argument #2 ($replacement) is an array, string given -TypeError: preg_replace(): Argument #2 ($replacement) must be of type array|string, stdClass given diff --git a/ext/pcre/tests/preg_split_error1.phpt b/ext/pcre/tests/preg_split_error1.phpt index 9e9fd8c7133d..309c494143c2 100644 --- a/ext/pcre/tests/preg_split_error1.phpt +++ b/ext/pcre/tests/preg_split_error1.phpt @@ -13,26 +13,11 @@ $regex_array = [ '/[a-zA-Z]', //Regex without closing delimiter '[a-zA-Z]/', //Regex without opening delimiter '/[a-zA-Z]/F', - [ - '[a-z]', //Array of Regexes - '[A-Z]', - '[0-9]', - ], '/[a-zA-Z]/', //Regex string ]; $subject = '1 2 a 3 4 b 5 6'; foreach ($regex_array as $regex_value) { - try { - var_dump(preg_split($regex_value, $subject)); - } catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; - } -} -$regex_value = new stdclass(); //Object -try { - var_dump(preg_split($regex_value, $subject)); -} catch (TypeError $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; + var_dump(preg_split($regex_value, $subject)); } ?> --EXPECTF-- @@ -47,7 +32,6 @@ bool(false) Warning: preg_split(): Unknown modifier 'F' in %spreg_split_error1.php on line %d bool(false) -TypeError: preg_split(): Argument #1 ($pattern) must be of type string, array given array(3) { [0]=> string(4) "1 2 " @@ -56,4 +40,3 @@ array(3) { [2]=> string(4) " 5 6" } -TypeError: preg_split(): Argument #1 ($pattern) must be of type string, stdClass given