]> granicus.if.org Git - php/commitdiff
Fixed bug #40754 (added substr() & substr_replace() overflow checks).
authorIlia Alshanetsky <iliaa@php.net>
Fri, 9 Mar 2007 01:58:34 +0000 (01:58 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Fri, 9 Mar 2007 01:58:34 +0000 (01:58 +0000)
NEWS
ext/standard/string.c
ext/standard/tests/strings/bug40754.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 754c58a095ea54b92cd52913cb68f56a044f0e99..be0774ce9234364bbc623f69085154e8d1b8035d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ PHP                                                                        NEWS
 - Added tidyNode::getParent() method (John, Nuno)
 - Fixed zend_llist_remove_tail (Michael Wallner, Dmitry)
 - Fixed a thread safety issue in gd gif read code (Nuno, Roman Nemecek)
+- Fixed bug #40754 (added substr() & substr_replace() overflow checks). (Ilia)
 - Fixed bug #40752 (parse_ini_file() segfaults when a scalar setting is 
   redeclared as an array). (Tony)
 - Fixed bug #40727 (segfault in PDO when failed to bind parameters). (Tony)
index 91f27ee54c8458d787e9de60f971f64d884db9e5..d05a9bfed2084da74f5471cb3b73c4a7d69c97de 100644 (file)
@@ -2063,11 +2063,17 @@ PHP_FUNCTION(substr)
        if (argc > 2) {
                convert_to_long_ex(len);
                l = Z_LVAL_PP(len);
+               if (l > Z_STRLEN_PP(str) || (l < 0 && -l > Z_STRLEN_PP(str))) {
+                       RETURN_FALSE;
+               }
        } else {
                l = Z_STRLEN_PP(str);
        }
        
        f = Z_LVAL_PP(from);
+       if (f > Z_STRLEN_PP(str) || (f < 0 && -f > Z_STRLEN_PP(str))) {
+               RETURN_FALSE;
+       }
 
        /* if "from" position is negative, count start position from the end
         * of the string
@@ -2190,6 +2196,12 @@ PHP_FUNCTION(substr_replace)
                                }
                        }
 
+                       if (f > Z_STRLEN_PP(str) || (f < 0 && -f > Z_STRLEN_PP(str))) {
+                               RETURN_FALSE;
+                       } else if (l > Z_STRLEN_PP(str) || (l < 0 && -l > Z_STRLEN_PP(str))) {
+                               RETURN_FALSE;
+                       }
+
                        if ((f + l) > Z_STRLEN_PP(str)) {
                                l = Z_STRLEN_PP(str) - f;
                        }
diff --git a/ext/standard/tests/strings/bug40754.phpt b/ext/standard/tests/strings/bug40754.phpt
new file mode 100644 (file)
index 0000000..f722ecc
--- /dev/null
@@ -0,0 +1,63 @@
+--TEST--
+Bug #40754 (Overflow checks inside string functions)
+--FILE--
+<?php
+
+$v = 2147483647;
+
+var_dump(substr("abcde", 1, $v));
+var_dump(substr_replace("abcde", "x", $v, $v));
+
+var_dump(strspn("abcde", "abc", $v, $v));
+var_dump(strcspn("abcde", "abc", $v, $v));
+
+var_dump(substr_count("abcde", "abc", $v, $v));
+var_dump(substr_compare("abcde", "abc", $v, $v));
+
+var_dump(stripos("abcde", "abc", $v));
+var_dump(substr_count("abcde", "abc", $v, 1));
+var_dump(substr_count("abcde", "abc", 1, $v));
+var_dump(strpos("abcde", "abc", $v));
+var_dump(stripos("abcde", "abc", $v));
+var_dump(strrpos("abcde", "abc", $v));
+var_dump(strripos("abcde", "abc", $v));
+var_dump(strncmp("abcde", "abc", $v));
+var_dump(chunk_split("abcde", $v, "abc"));
+var_dump(substr("abcde", $v, $v));
+
+?>
+--EXPECTF--    
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: substr_count(): Offset value 2147483647 exceeds string length. in %s/bug40754.php on line %d
+bool(false)
+
+Warning: substr_compare(): The start position cannot exceed initial string length in %s/bug40754.php on line %d
+bool(false)
+
+Warning: stripos(): Offset not contained in string. in %s/bug40754.php on line %d
+bool(false)
+
+Warning: substr_count(): Offset value 2147483647 exceeds string length. in %s/bug40754.php on line %d
+bool(false)
+
+Warning: substr_count(): Length value 2147483647 exceeds string length. in %s/bug40754.php on line %d
+bool(false)
+
+Warning: strpos(): Offset not contained in string. in %s/bug40754.php on line %d
+bool(false)
+
+Warning: stripos(): Offset not contained in string. in %s/bug40754.php on line %d
+bool(false)
+
+Notice: strrpos(): Offset is greater than the length of haystack string in %s/bug40754.php on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s/bug40754.php on line %d
+bool(false)
+int(2)
+string(8) "abcdeabc"
+bool(false)