Skip to content

Promote warnings to exceptions in ext/pcre #6006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
32 changes: 17 additions & 15 deletions ext/pcre/php_pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ static zend_string **make_subpats_table(uint32_t num_subpats, pcre_cache_entry *
const char *name = name_table + 2;
subpat_names[name_idx] = zend_string_init(name, strlen(name), 0);
if (is_numeric_string(ZSTR_VAL(subpat_names[name_idx]), ZSTR_LEN(subpat_names[name_idx]), NULL, NULL, 0) > 0) {
php_error_docref(NULL, E_WARNING, "Numeric named subpatterns are not allowed");
zend_value_error("%s(): Numeric named subpatterns are not allowed", get_active_function_name());
free_subpats_table(subpat_names, num_subpats);
return NULL;
}
Expand Down Expand Up @@ -621,8 +621,12 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
if (key != regex) {
zend_string_release_ex(key, 0);
}
php_error_docref(NULL, E_WARNING,
p < ZSTR_VAL(regex) + ZSTR_LEN(regex) ? "Null byte in regex" : "Empty regular expression");

if (p < ZSTR_VAL(regex) + ZSTR_LEN(regex)) {
zend_type_error("%s(): Regular expression cannot contain any null-bytes", get_active_function_name());
} else {
zend_value_error("%s(): Regular expression cannot be empty", get_active_function_name());
}
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
return NULL;
}
Expand All @@ -634,7 +638,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
if (key != regex) {
zend_string_release_ex(key, 0);
}
php_error_docref(NULL,E_WARNING, "Delimiter must not be alphanumeric or backslash");
zend_value_error("%s(): Regular expression delimiter cannot be alphanumeric or a backslash", get_active_function_name());
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
return NULL;
}
Expand Down Expand Up @@ -678,11 +682,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
zend_string_release_ex(key, 0);
}
if (pp < ZSTR_VAL(regex) + ZSTR_LEN(regex)) {
php_error_docref(NULL,E_WARNING, "Null byte in regex");
zend_type_error("%s(): Regular expression cannot contain any null-bytes", get_active_function_name());
} else if (start_delimiter == end_delimiter) {
php_error_docref(NULL,E_WARNING, "No ending delimiter '%c' found", delimiter);
zend_value_error("%s(): Regular expression doesn't contain an ending delimiter \"%c\"", get_active_function_name(), delimiter);
} else {
php_error_docref(NULL,E_WARNING, "No ending matching delimiter '%c' found", delimiter);
zend_value_error("%s(): No ending matching delimiter \"%c\" found", get_active_function_name(), delimiter);
}
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
return NULL;
Expand Down Expand Up @@ -731,9 +735,9 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in

default:
if (pp[-1]) {
php_error_docref(NULL,E_WARNING, "Unknown modifier '%c'", pp[-1]);
zend_value_error("%s(): Regular expression modifier \"%c\" is invalid", get_active_function_name(), pp[-1]);
} else {
php_error_docref(NULL,E_WARNING, "Null byte in regex");
zend_type_error("%s(): Regular expression cannot contain any null-bytes", get_active_function_name());
}
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
efree(pattern);
Expand All @@ -745,7 +749,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
}

if (poptions & PREG_REPLACE_EVAL) {
php_error_docref(NULL, E_WARNING, "The /e modifier is no longer supported, use preg_replace_callback instead");
zend_value_error("%s(): Regular expression modifier \"e\" is no longer supported, use preg_replace_callback instead", get_active_function_name());
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
efree(pattern);
if (key != regex) {
Expand Down Expand Up @@ -1193,7 +1197,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
}
if ((global && (subpats_order < PREG_PATTERN_ORDER || subpats_order > PREG_SET_ORDER)) ||
(!global && subpats_order != 0)) {
php_error_docref(NULL, E_WARNING, "Invalid flags specified");
zend_argument_value_error(4, "must be a PREG_* constant");
return;
}
} else {
Expand Down Expand Up @@ -2404,15 +2408,13 @@ PHP_FUNCTION(preg_replace_callback_array)

ZEND_HASH_FOREACH_STR_KEY_VAL(pattern, str_idx_regex, replace) {
if (!str_idx_regex) {
php_error_docref(NULL, E_WARNING, "Delimiter must not be alphanumeric or backslash");
zend_value_error("%s(): Regular expression delimiter cannot be alphanumeric or a backslash", get_active_function_name());
zval_ptr_dtor(return_value);
RETURN_NULL();
}

if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) {
zend_string *callback_name = zend_get_callable_name(replace);
zend_type_error("'%s' is not a valid callback", ZSTR_VAL(callback_name));
zend_string_release_ex(callback_name, 0);
zend_argument_type_error(1, "must contain only valid callbacks");
RETURN_THROWS();
}

Expand Down
20 changes: 13 additions & 7 deletions ext/pcre/tests/002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@ preg_* with bogus vals
--FILE--
<?php

var_dump(preg_match_all('//', '', $dummy, 0xdead));
try {
preg_match_all('//', '', $dummy, 0xdead);
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_quote(''));

var_dump(preg_replace('/(.)/', '${1}${1', 'abc'));
var_dump(preg_replace('/.++\d*+[/', 'for ($', 'abc'));
var_dump(preg_replace('/(.)/e', 'for ($', 'abc'));

try {
preg_replace('/(.)/e', 'for ($', 'abc');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

?>
--EXPECTF--
Warning: preg_match_all(): Invalid flags specified in %s002.php on line %d
NULL
preg_match_all(): Argument #4 ($flags) must be a PREG_* constant
string(0) ""
string(12) "a${1b${1c${1"

Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 8 in %s002.php on line %d
NULL

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in %s on line %d
NULL
preg_replace(): Regular expression modifier "e" is no longer supported, use preg_replace_callback instead
27 changes: 18 additions & 9 deletions ext/pcre/tests/bug73392.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@ class Foo {
function b() {
return "b";
}
var_dump(preg_replace_callback_array(
array(
"/a/" => 'b', "/b/" => function () { return "c"; }, "/c/" => new Rep, "reporting" => array("Foo", "rep"), "a1" => array("Foo", "rep"),
), 'a'));
?>
--EXPECTF--
Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d

Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d
NULL
try {
preg_replace_callback_array(
array(
"/a/" => 'b',
"/b/" => function () { return "c"; },
"/c/" => new Rep,
"reporting" => array("Foo", "rep"),
"a1" => array("Foo", "rep"),
),
'a'
);
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

?>
--EXPECT--
preg_replace_callback_array(): Regular expression delimiter cannot be alphanumeric or a backslash
69 changes: 45 additions & 24 deletions ext/pcre/tests/delimiters.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,56 @@ Delimiters crash test
--FILE--
<?php

var_dump(preg_match('', ''));
var_dump(preg_match(' ', ''));
try {
preg_match('', '');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

try {
preg_match(' ', '');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_match('@@', ''));
var_dump(preg_match('12', ''));

try {
preg_match('12', '');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_match('<>', ''));
var_dump(preg_match('~a', ''));

try {
preg_match('~a', '');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_match('@\@\@@', '@@'));
var_dump(preg_match('//z', '@@'));
var_dump(preg_match('{', ''));

?>
--EXPECTF--
Warning: preg_match(): Empty regular expression in %sdelimiters.php on line 3
bool(false)
try {
preg_match('//z', '@@');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Empty regular expression in %sdelimiters.php on line 4
bool(false)
int(1)
try {
preg_match('{', '');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Delimiter must not be alphanumeric or backslash in %sdelimiters.php on line 6
bool(false)
?>
--EXPECT--
preg_match(): Regular expression cannot be empty
preg_match(): Regular expression cannot be empty
int(1)

Warning: preg_match(): No ending delimiter '~' found in %sdelimiters.php on line 8
bool(false)
preg_match(): Regular expression delimiter cannot be alphanumeric or a backslash
int(1)

Warning: preg_match(): Unknown modifier 'z' in %sdelimiters.php on line 10
bool(false)

Warning: preg_match(): No ending matching delimiter '}' found in %sdelimiters.php on line 11
bool(false)
preg_match(): Regular expression doesn't contain an ending delimiter "~"
int(1)
preg_match(): Regular expression modifier "z" is invalid
preg_match(): No ending matching delimiter "}" found
12 changes: 8 additions & 4 deletions ext/pcre/tests/errors03.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ Test preg_match() function : error conditions - Internal error
--FILE--
<?php

var_dump(preg_match('/', 'Hello world'));
try {
preg_match('/', 'Hello world');
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_last_error_msg() === 'Internal error');

?>
--EXPECTF--
Warning: preg_match(): No ending delimiter '/' found in %s on line %d
bool(false)
--EXPECT--
preg_match(): Regular expression doesn't contain an ending delimiter "/"
bool(true)
9 changes: 6 additions & 3 deletions ext/pcre/tests/match_flags3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ preg_match() flags 3
--FILE--
<?php

var_dump(preg_match('', '', $match, 0xfff));
try {
preg_match('', '', $match, 0xfff);
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}

var_dump(preg_match('/\d+/', '123 456 789 012', $match, 0, -8));
var_dump($match);
Expand All @@ -18,8 +22,7 @@ var_dump(preg_match('/(?P<3>)/', ''));

?>
--EXPECTF--
Warning: preg_match(): Empty regular expression in %smatch_flags3.php on line 3
bool(false)
preg_match(): Regular expression cannot be empty
int(1)
array(1) {
[0]=>
Expand Down
94 changes: 68 additions & 26 deletions ext/pcre/tests/null_bytes.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,82 @@ Zero byte test
--FILE--
<?php

preg_match("\0//i", "");
preg_match("/\0/i", "");
preg_match("//\0i", "");
preg_match("//i\0", "");
preg_match("/\\\0/i", "");
try {
preg_match("\0//i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

preg_match("\0[]i", "");
preg_match("[\0]i", "");
preg_match("[]\0i", "");
preg_match("[]i\0", "");
preg_match("[\\\0]i", "");
try {
preg_match("/\0/i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

preg_replace("/foo/e\0/i", "echo('Eek');", "");
try {
preg_match("//\0i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

?>
--EXPECTF--
Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 3

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 4
try {
preg_match("//i\0", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 5
try {
preg_match("/\\\0/i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 6
try {
preg_match("\0[]i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 7
try {
preg_match("[\0]i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 9
try {
preg_match("[]\0i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 10
try {
preg_match("[]i\0", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 11
try {
preg_match("[\\\0]i", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 12
try {
preg_replace("/foo/e\0/i", "echo('Eek');", "");
} catch (TypeError $exception) {
echo $exception->getMessage() . "\n";
}

Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 13

Warning: preg_replace(): Null byte in regex in %snull_bytes.php on line 15
?>
--EXPECT--
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_match(): Regular expression cannot contain any null-bytes
preg_replace(): Regular expression cannot contain any null-bytes
Loading