substr_count(): Support negative values for '$offset' and '$length' parameters.

This commit is contained in:
Francois Laupretre 2015-07-23 04:01:23 +02:00 committed by Nikita Popov
parent 56fce8990f
commit 1c3e1a3d28
4 changed files with 33 additions and 36 deletions

View File

@ -5293,12 +5293,10 @@ PHP_FUNCTION(substr_count)
endp = p + haystack_len;
if (offset < 0) {
php_error_docref(NULL, E_WARNING, "Offset should be greater than or equal to 0");
RETURN_FALSE;
offset += (zend_long)haystack_len;
}
if ((size_t)offset > haystack_len) {
php_error_docref(NULL, E_WARNING, "Offset value " ZEND_LONG_FMT " exceeds string length", offset);
if ((offset < 0) || ((size_t)offset > haystack_len)) {
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
p += offset;
@ -5306,11 +5304,10 @@ PHP_FUNCTION(substr_count)
if (ac == 4) {
if (length <= 0) {
php_error_docref(NULL, E_WARNING, "Length should be greater than 0");
RETURN_FALSE;
length += (haystack_len - offset);
}
if (length > (haystack_len - offset)) {
php_error_docref(NULL, E_WARNING, "Length value " ZEND_LONG_FMT " exceeds string length", length);
if ((length <= 0) || (length > (haystack_len - offset))) {
php_error_docref(NULL, E_WARNING, "Invalid length value");
RETURN_FALSE;
}
endp = p + length;

View File

@ -32,7 +32,7 @@ var_dump(substr("abcde", $v, $v));
bool(false)
bool(false)
Warning: substr_count(): Offset value 2147483647 exceeds string length in %s on line %d
Warning: substr_count(): Offset not contained in string in %s on line %d
bool(false)
Warning: substr_compare(): The start position cannot exceed initial string length in %s on line %d
@ -41,10 +41,10 @@ bool(false)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
Warning: substr_count(): Offset value 2147483647 exceeds string length in %s on line %d
Warning: substr_count(): Offset not contained in string in %s on line %d
bool(false)
Warning: substr_count(): Length value 2147483647 exceeds string length in %s on line %d
Warning: substr_count(): Invalid length value in %s on line %d
bool(false)
Warning: strpos(): Offset not contained in string in %s on line %d

View File

@ -9,12 +9,17 @@ var_dump(@substr_count("a", ""));
var_dump(@substr_count("", "a"));
var_dump(@substr_count("", "a"));
var_dump(@substr_count("", chr(0)));
$a = str_repeat("abcacba", 100);
var_dump(@substr_count($a, "bca"));
$a = str_repeat("abcacbabca", 100);
var_dump(@substr_count($a, "bca"));
var_dump(substr_count($a, "bca", 200));
var_dump(substr_count($a, "bca", 200, 50));
var_dump(substr_count($a, "bca", -200));
var_dump(substr_count($a, "bca", -200, 50));
var_dump(substr_count($a, "bca", -200, -50));
echo "Done\n";
@ -30,4 +35,7 @@ int(100)
int(200)
int(160)
int(10)
int(40)
int(10)
int(30)
Done

View File

@ -4,25 +4,29 @@ Test substr_count() function (error conditions)
<?php
echo "\n*** Testing error conditions ***\n";
$str = 'abcdefghik';
/* Zero argument */
var_dump( substr_count() );
/* more than expected no. of args */
var_dump( substr_count($str, "t", 0, 15, 30) );
/* offset as negative value */
var_dump(substr_count($str, "t", -5));
/* offset before start */
var_dump(substr_count($str, "t", -20));
/* offset > size of the string */
var_dump(substr_count($str, "t", 25));
/* Using offset and length to go beyond the size of the string:
Warning message expected, as length+offset > length of string */
var_dump( substr_count($str, "i", 5, 15) );
var_dump( substr_count($str, "i", 5, 7) );
/* length as Null */
var_dump( substr_count($str, "t", "", "") );
var_dump( substr_count($str, "i", NULL, NULL) );
/* Invalid offset argument */
var_dump( substr_count($str, "t", "") );
/* length too small */
var_dump( substr_count($str, "t", 2, -20) );
echo "Done\n";
@ -33,33 +37,21 @@ echo "Done\n";
Warning: substr_count() expects at least 2 parameters, 0 given in %s on line %d
NULL
Notice: Undefined variable: str in %s on line %d
Warning: substr_count() expects at most 4 parameters, 5 given in %s on line %d
NULL
Notice: Undefined variable: str in %s on line %d
Warning: substr_count(): Offset should be greater than or equal to 0 in %s on line %d
Warning: substr_count(): Offset not contained in string in %s on line %d
bool(false)
Notice: Undefined variable: str in %s on line %d
Warning: substr_count(): Offset value 25 exceeds string length in %s on line %d
Warning: substr_count(): Offset not contained in string in %s on line %d
bool(false)
Notice: Undefined variable: str in %s on line %d
Warning: substr_count(): Offset value 5 exceeds string length in %s on line %d
Warning: substr_count(): Invalid length value in %s on line %d
bool(false)
Notice: Undefined variable: str in %s on line %d
Warning: substr_count() expects parameter 3 to be integer, string given in %s on line %d
NULL
Notice: Undefined variable: str in %s on line %d
Warning: substr_count(): Length should be greater than 0 in %s on line %d
Warning: substr_count(): Invalid length value in %s on line %d
bool(false)
Done