Skip to content

Commit e292391

Browse files
committed
Allow zero length comparison
1 parent 86d9235 commit e292391

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed

ext/standard/string.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5585,14 +5585,13 @@ PHP_FUNCTION(substr_compare)
55855585
int s1_len, s2_len;
55865586
long offset, len=0;
55875587
zend_bool cs=0;
5588-
uint cmp_len;
55895588

55905589
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl|lb", &s1, &s1_len, &s2, &s2_len, &offset, &len, &cs) == FAILURE) {
55915590
RETURN_FALSE;
55925591
}
55935592

5594-
if (ZEND_NUM_ARGS() >= 4 && len <= 0) {
5595-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The length must be greater than zero");
5593+
if (ZEND_NUM_ARGS() >= 4 && len < 0) {
5594+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The length must be greater than or equal to zero");
55965595
RETURN_FALSE;
55975596
}
55985597

@@ -5606,12 +5605,10 @@ PHP_FUNCTION(substr_compare)
56065605
RETURN_FALSE;
56075606
}
56085607

5609-
cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));
5610-
56115608
if (!cs) {
5612-
RETURN_LONG(zend_binary_strncmp(s1 + offset, (s1_len - offset), s2, s2_len, cmp_len));
5609+
RETURN_LONG(zend_binary_strncmp(s1 + offset, (s1_len - offset), s2, s2_len, (uint)len));
56135610
} else {
5614-
RETURN_LONG(zend_binary_strncasecmp_l(s1 + offset, (s1_len - offset), s2, s2_len, cmp_len));
5611+
RETURN_LONG(zend_binary_strncasecmp_l(s1 + offset, (s1_len - offset), s2, s2_len, (uint)len));
56155612
}
56165613
}
56175614
/* }}} */

ext/standard/tests/strings/bug33605.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
Bug #33605 (substr_compare crashes)
33
--FILE--
44
<?php
5-
$res = substr_compare("aa", "a", -99999999, 0, 0);
5+
$res = substr_compare("aa", "a", -99999999, -1, 0);
66
var_dump($res);
77

88
?>
99
--EXPECTF--
10-
Warning: substr_compare(): The length must be greater than zero in %s on line %d
10+
Warning: substr_compare(): The length must be greater than or equal to zero in %s on line %d
1111
bool(false)

ext/standard/tests/strings/substr_compare.phpt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ var_dump(substr_compare("abcde", "bc", 1, 3));
1010
var_dump(substr_compare("abcde", "cd", 1, 2));
1111
var_dump(substr_compare("abcde", "abc", 5, 1));
1212
var_dump(substr_compare("abcde", "abcdef", -10, 10));
13-
13+
var_dump(substr_compare("abcde", "abc", 0, 0));
1414
var_dump(substr_compare("abcde", -1, 0, NULL, new stdClass));
1515
echo "Test\n";
16+
var_dump(substr_compare("abcde", "abc", 0, -1));
1617
var_dump(substr_compare("abcde", "abc", -1, NULL, -5));
1718
var_dump(substr_compare("abcde", -1, 0, "str", new stdClass));
1819

@@ -28,13 +29,15 @@ int(-1)
2829
Warning: substr_compare(): The start position cannot exceed initial string length in %s on line %d
2930
bool(false)
3031
int(-1)
32+
int(0)
3133

3234
Warning: substr_compare() expects parameter 5 to be boolean, object given in %s on line %d
3335
bool(false)
3436
Test
3537

36-
Warning: substr_compare(): The length must be greater than zero in %s on line %d
38+
Warning: substr_compare(): The length must be greater than or equal to zero in %s on line %d
3739
bool(false)
40+
int(0)
3841

3942
Warning: substr_compare() expects parameter 4 to be long, string given in %s on line %d
4043
bool(false)

0 commit comments

Comments
 (0)