]> granicus.if.org Git - php/commitdiff
fix possible substr_compare() crash
authorAntony Dovgal <tony2001@php.net>
Tue, 25 Apr 2006 12:48:42 +0000 (12:48 +0000)
committerAntony Dovgal <tony2001@php.net>
Tue, 25 Apr 2006 12:48:42 +0000 (12:48 +0000)
add new tests

ext/standard/string.c
ext/standard/tests/strings/bug33605.phpt [new file with mode: 0644]
ext/standard/tests/strings/substr_compare.phpt [new file with mode: 0644]

index 21936dee5b1e52ed1a3dbcde70542ab900024585..c923e84ab006bf40b779d34e1df074a1ab82dd75 100644 (file)
@@ -4884,13 +4884,19 @@ PHP_FUNCTION(substr_compare)
                RETURN_FALSE;
        }
 
-       if ((offset + len) >= s1_len) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length.");
+       if (ZEND_NUM_ARGS() >= 4 && len <= 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The length must be greater than zero");
                RETURN_FALSE;
        }
 
        if (offset < 0) {
                offset = s1_len + offset;
+               offset = (offset < 0) ? 0 : offset;
+       }
+
+       if ((offset + len) >= s1_len) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length");
+               RETURN_FALSE;
        }
 
        cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));
diff --git a/ext/standard/tests/strings/bug33605.phpt b/ext/standard/tests/strings/bug33605.phpt
new file mode 100644 (file)
index 0000000..f0c49eb
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Bug #33605 (substr_compare crashes)
+--FILE--
+<?php
+$res = substr_compare("aa", "a", -99999999, 0, 0);
+var_dump($res);
+
+?>
+--EXPECTF--
+Warning: substr_compare(): The length must be greater than zero in %s on line %d
+bool(false)
diff --git a/ext/standard/tests/strings/substr_compare.phpt b/ext/standard/tests/strings/substr_compare.phpt
new file mode 100644 (file)
index 0000000..9486c16
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+substr_compare()
+--FUNCTIONS--
+substr_compare
+--FILE--
+<?php
+
+var_dump(substr_compare("abcde", "bc", 1, 2));
+var_dump(substr_compare("abcde", "bcg", 1, 2));
+var_dump(substr_compare("abcde", "BC", 1, 2, true));
+var_dump(substr_compare("abcde", "bc", 1, 3));
+var_dump(substr_compare("abcde", "cd", 1, 2));
+var_dump(substr_compare("abcde", "abc", 5, 1));
+
+var_dump(substr_compare("abcde", -1, 0, NULL, new stdClass));
+echo "Test\n";
+var_dump(substr_compare("abcde", "abc", -1, NULL, -5));
+var_dump(substr_compare("abcde", -1, 0, "str", new stdClass));
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(0)
+int(0)
+int(0)
+int(1)
+int(-1)
+
+Warning: substr_compare(): The start position cannot exceed initial string length in %s on line %d
+bool(false)
+
+Warning: substr_compare() expects parameter 5 to be boolean, object given in %s on line %d
+bool(false)
+Test
+
+Warning: substr_compare(): The length must be greater than zero in %s on line %d
+bool(false)
+
+Warning: substr_compare() expects parameter 4 to be long, string given in %s on line %d
+bool(false)
+Done