Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions ext/pcre/php_pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you either need to guard it or update config0.m4 min. version check (was added for 10.38).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I might try and upgrade the minimal version to 10.40.

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);
Expand Down
4 changes: 2 additions & 2 deletions ext/pcre/tests/bug70345.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions ext/pcre/tests/bug75457.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
--TEST--
Bug #75457 (heap-use-after-free in php7.0.25)
--SKIPIF--
<?php
if (PCRE_VERSION_MAJOR >= 10 && PCRE_VERSION_MINOR >= 45) {
die("skip callout feature is disable in PCRE2 10.45 and above");
}
?>
--FILE--
<?php
$pattern = "/(((?(?C)0?=))(?!()0|.(?0)0)())/";
Expand Down
19 changes: 19 additions & 0 deletions ext/pcre/tests/callout_syntax_in_pattern.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
PCRE2 callout feature is not supported.
--SKIPIF--
<?php
if (PCRE_VERSION_MAJOR >= 10 && PCRE_VERSION_MINOR >= 45) {
die("skip callout feature is disable in PCRE2 10.45 and above");
}
?>
--FILE--
<?php

$subject = 'hello';
$pattern = '/a(?C1)b(?C2)c/';

var_dump(preg_match($pattern, $subject));

?>
--EXPECT--
int(0)
Comment on lines +6 to +13

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'hello' has no 'a' in it...and so, matching will never reach either callout point at all...which means int(0) does not really show that callouts are not supported, I guess it only shows the pattern compiles...or am I missing something here?

20 changes: 20 additions & 0 deletions ext/pcre/tests/callout_syntax_in_pattern_disabled.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
PCRE2 callout feature is not supported and disabled if pcre2 lib permits it.
--SKIPIF--
<?php
if (!(PCRE_VERSION_MAJOR >= 10 && PCRE_VERSION_MINOR >= 45)) {
die("skip needs 10.45 or above");
}
?>
--FILE--
<?php

$subject = 'hello';
$pattern = '/a(?C1)b(?C2)c/';

var_dump(preg_match($pattern, $subject));

?>
--EXPECTF--
Warning: preg_match(): Compilation failed: using callouts is disabled by the application at offset 4 in %s on line %d
bool(false)
25 changes: 25 additions & 0 deletions ext/pcre/tests/disabled_pcre_compile_options.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
Disabled PCRE2 regex compilation features.
--FILE--
<?php

$subject = 'hello';
$patterns = [
'/\u/', // Unknown unicode escape sequence
'/\C/u', // \C in unicode
'/a(?=b\K)/', // \K in look around
];

foreach ($patterns as $pattern) {
var_dump(preg_match($pattern, $subject));
}
?>
--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)
17 changes: 0 additions & 17 deletions ext/pcre/tests/preg_grep_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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--
Expand All @@ -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
23 changes: 2 additions & 21 deletions ext/pcre/tests/preg_match_all_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]=>
Expand All @@ -69,5 +52,3 @@ array(1) {
string(1) "t"
}
}
TypeError: preg_match_all(): Argument #1 ($pattern) must be of type string, stdClass given
NULL
7 changes: 0 additions & 7 deletions ext/pcre/tests/preg_replace_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
12 changes: 4 additions & 8 deletions ext/pcre/tests/preg_replace_error2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
19 changes: 1 addition & 18 deletions ext/pcre/tests/preg_split_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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--
Expand All @@ -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 "
Expand All @@ -56,4 +40,3 @@ array(3) {
[2]=>
string(4) " 5 6"
}
TypeError: preg_split(): Argument #1 ($pattern) must be of type string, stdClass given
Loading