Commit:    8b3c1a380a182655113b94b0b96551e98d05a8d3
Author:    Stanislav Malyshev <s...@php.net>         Sat, 30 Jun 2012 16:31:26 
-0700
Parents:   f82dd2c77463e01cbcc9912be08f5e45cb1a384c
Branches:  PHP-5.4 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=8b3c1a380a182655113b94b0b96551e98d05a8d3

Log:
fix bug #55856: preg_replace should fail on trailing garbage

Bugs:
https://bugs.php.net/55856

Changed paths:
  M  NEWS
  M  ext/pcre/php_pcre.c
  A  ext/pcre/tests/null_bytes.phpt


Diff:
diff --git a/NEWS b/NEWS
index 770b160..a6c68a2 100644
--- a/NEWS
+++ b/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)
 
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index c9d7072..f61364c 100644
--- a/ext/pcre/php_pcre.c
+++ b/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,21 +293,18 @@ 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
@@ -314,7 +312,6 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char 
*regex, int regex_le
                 * 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;
                }
diff --git a/ext/pcre/tests/null_bytes.phpt b/ext/pcre/tests/null_bytes.phpt
new file mode 100644
index 0000000..9a3f433
--- /dev/null
+++ b/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


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to