Permalink
Browse files

fix bug #55856: preg_replace should fail on trailing garbage

  • Loading branch information...
1 parent f82dd2c commit 8b3c1a380a182655113b94b0b96551e98d05a8d3 @smalyshev smalyshev committed Jun 30, 2012
Showing with 66 additions and 12 deletions.
  1. +4 −0 NEWS
  2. +20 −12 ext/pcre/php_pcre.c
  3. +42 −0 ext/pcre/tests/null_bytes.phpt
View
4 NEWS
@@ -39,6 +39,10 @@ PHP NEWS
- Installation:
. Fixed bug #62460 (php binaries installed as binary.dSYM). (Reeze Xia)
+- PCRE:
+ . Fixed bug #55856 (preg_replace should fail on trailing garbage).
+ (reg dot php at alf dot nu)
+
- PDO:
. Fixed bug #62685 (Wrong return datatype in PDO::inTransaction()). (Laruence)
View
32 ext/pcre/php_pcre.c
@@ -275,7 +275,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
get to the end without encountering a delimiter. */
while (isspace((int)*(unsigned char *)p)) p++;
if (*p == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty regular expression");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ p < regex + regex_len ? "Null byte in regex" : "Empty regular expression");
return NULL;
}
@@ -292,29 +293,25 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
delimiter = pp[5];
end_delimiter = delimiter;
+ pp = p;
+
if (start_delimiter == end_delimiter) {
/* We need to iterate through the pattern, searching for the ending delimiter,
but skipping the backslashed delimiters. If the ending delimiter is not
found, display a warning. */
- pp = p;
while (*pp != 0) {
if (*pp == '\\' && pp[1] != 0) pp++;
else if (*pp == delimiter)
break;
pp++;
}
- if (*pp == 0) {
- php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending delimiter '%c' found", delimiter);
- return NULL;
- }
} else {
/* We iterate through the pattern, searching for the matching ending
* delimiter. For each matching starting delimiter, we increment nesting
* level, and decrement it for each matching ending delimiter. If we
* reach the end of the pattern without matching, display a warning.
*/
int brackets = 1; /* brackets nesting level */
- pp = p;
while (*pp != 0) {
if (*pp == '\\' && pp[1] != 0) pp++;
else if (*pp == end_delimiter && --brackets <= 0)
@@ -323,10 +320,17 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
brackets++;
pp++;
}
- if (*pp == 0) {
- php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending matching delimiter '%c' found", end_delimiter);
- return NULL;
+ }
+
+ if (*pp == 0) {
+ if (pp < regex + regex_len) {
+ php_error_docref(NULL TSRMLS_CC,E_WARNING, "Null byte in regex");
+ } else if (start_delimiter == end_delimiter) {
+ php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending delimiter '%c' found", delimiter);
+ } else {
+ php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending matching delimiter '%c' found", delimiter);
}
+ return NULL;
}
/* Make a copy of the actual pattern. */
@@ -337,7 +341,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
/* Parse through the options, setting appropriate flags. Display
a warning if we encounter an unknown modifier. */
- while (*pp != 0) {
+ while (pp < regex + regex_len) {
switch (*pp++) {
/* Perl compatible options */
case 'i': coptions |= PCRE_CASELESS; break;
@@ -368,7 +372,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
break;
default:
- php_error_docref(NULL TSRMLS_CC,E_WARNING, "Unknown modifier '%c'", pp[-1]);
+ if (pp[-1]) {
+ php_error_docref(NULL TSRMLS_CC,E_WARNING, "Unknown modifier '%c'", pp[-1]);
+ } else {
+ php_error_docref(NULL TSRMLS_CC,E_WARNING, "Null byte in regex");
+ }
efree(pattern);
return NULL;
}
View
42 ext/pcre/tests/null_bytes.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Zero byte test
+--FILE--
+<?php
+
+preg_match("\0//i", "");
+preg_match("/\0/i", "");
+preg_match("//\0i", "");
+preg_match("//i\0", "");
+preg_match("/\\\0/i", "");
+
+preg_match("\0[]i", "");
+preg_match("[\0]i", "");
+preg_match("[]\0i", "");
+preg_match("[]i\0", "");
+preg_match("[\\\0]i", "");
+
+preg_replace("/foo/e\0/i", "echo('Eek');", "");
+
+?>
+--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
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 5
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 6
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 7
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 9
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 10
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 11
+
+Warning: preg_match(): Null byte in regex in %snull_bytes.php on line 12
+
+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

0 comments on commit 8b3c1a3

Please sign in to comment.