Browse Source

strpos()/stripos(): Add support for negative offsets

pull/1431/merge
Francois Laupretre 11 years ago
committed by Nikita Popov
parent
commit
56fce8990f
  1. 1
      ext/iconv/tests/iconv_strpos.phpt
  2. 230
      ext/mbstring/tests/bug45923.phpt
  3. 6
      ext/standard/string.c
  4. 20
      ext/standard/tests/strings/stripos_basic2.phpt
  5. 15
      ext/standard/tests/strings/stripos_error.phpt
  6. 6
      ext/standard/tests/strings/stripos_variation14.phpt
  7. BIN
      ext/standard/tests/strings/strpos.phpt
  8. 5
      tests/lang/bug22592.phpt

1
ext/iconv/tests/iconv_strpos.phpt

@ -37,7 +37,6 @@ var_dump(iconv_strpos("", "string"));
?>
--EXPECTF--
2: %s
bool(false)
2: %s
bool(false)

230
ext/mbstring/tests/bug45923.phpt

@ -6,197 +6,253 @@ Bug #45923 (mb_st[r]ripos() offset not handled correctly)
mbstring.internal_encoding=UTF-8
--FILE--
<?php
var_dump(strpos("abc abc abc", "abc", 0));
var_dump(strpos("abc abc abc", "abc", 3));
var_dump(strpos("abc abc abc", "abc", 6));
var_dump(strpos("abc abc abc", "abc", 9));
var_dump(strpos("abc abc abc", "abc", 11));
var_dump(strpos("abc abc abc", "abc", 12));
var_dump(strpos("abc abc abc", "abc", -1));
var_dump(strpos("abc abc abc", "abc", -3));
var_dump(strpos("abc abc abc", "abc", -6));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 0));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 3));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 6));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 9));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 11));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", 12));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", -1));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", -3));
var_dump(mb_strpos("●○◆ ●○◆ ●○◆", "●○◆", -6));
var_dump(stripos("abc abc abc", "abc", 0));
var_dump(stripos("abc abc abc", "abc", 3));
var_dump(stripos("abc abc abc", "abc", 6));
var_dump(stripos("abc abc abc", "abc", 9));
var_dump(stripos("abc abc abc", "abc", 11));
var_dump(stripos("abc abc abc", "abc", 12));
var_dump(stripos("abc abc abc", "abc", -1));
var_dump(stripos("abc abc abc", "abc", -3));
var_dump(stripos("abc abc abc", "abc", -6));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 0));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 3));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 6));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 9));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 11));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", 12));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", -1));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", -3));
var_dump(mb_stripos("●○◆ ●○◆ ●○◆", "●○◆", -6));
var_dump(strrpos("abc abc abc", "abc", 0));
var_dump(strrpos("abc abc abc", "abc", 3));
var_dump(strrpos("abc abc abc", "abc", 6));
var_dump(strrpos("abc abc abc", "abc", 9));
var_dump(strrpos("abc abc abc", "abc", 11));
var_dump(strrpos("abc abc abc", "abc", 12));
var_dump(strrpos("abc abc abc", "abc", -1));
var_dump(strrpos("abc abc abc", "abc", -3));
var_dump(strrpos("abc abc abc", "abc", -6));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 0));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 3));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 6));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 9));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 11));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", 12));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", -1));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", -3));
var_dump(mb_strrpos("●○◆ ●○◆ ●○◆", "●○◆", -6));
var_dump(strripos("abc abc abc", "abc", 0));
var_dump(strripos("abc abc abc", "abc", 3));
var_dump(strripos("abc abc abc", "abc", 6));
var_dump(strripos("abc abc abc", "abc", 9));
var_dump(strripos("abc abc abc", "abc", 11));
var_dump(strripos("abc abc abc", "abc", 12));
var_dump(strripos("abc abc abc", "abc", -1));
var_dump(strripos("abc abc abc", "abc", -3));
var_dump(strripos("abc abc abc", "abc", -6));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 0));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 3));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 6));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 9));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 11));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", 12));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", -1));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", -3));
var_dump(mb_strripos("●○◆ ●○◆ ●○◆", "●○◆", -6));
function section($func, $haystack, $needle)
{
echo "\n------- $func -----------\n\n";
foreach(array(0, 3, 6, 9, 11, 12, -1, -3, -6, -20) as $offset) {
echo "> Offset: $offset\n";
var_dump($func($haystack,$needle,$offset));
}
}
section('strpos' , "abc abc abc" , "abc");
section('mb_strpos' , "●○◆ ●○◆ ●○◆", "●○◆");
section('stripos' , "abc abc abc" , "abc");
section('mb_stripos' , "●○◆ ●○◆ ●○◆", "●○◆");
section('strrpos' , "abc abc abc" , "abc");
section('mb_strrpos' , "●○◆ ●○◆ ●○◆", "●○◆");
section('strripos' , "abc abc abc" , "abc");
section('mb_strripos', "●○◆ ●○◆ ●○◆", "●○◆");
?>
--EXPECTF--
------- strpos -----------
> Offset: 0
int(0)
> Offset: 3
int(4)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: strpos(): Offset not contained in string in %s on line %d
bool(false)
Warning: strpos(): Offset not contained in string in %s on line %d
> Offset: -1
bool(false)
> Offset: -3
int(8)
> Offset: -6
int(8)
> Offset: -20
Warning: strpos(): Offset not contained in string in %s on line %d
bool(false)
Warning: strpos(): Offset not contained in string in %s on line %d
bool(false)
------- mb_strpos -----------
> Offset: 0
int(0)
> Offset: 3
int(4)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: mb_strpos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -1
Warning: mb_strpos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -3
Warning: mb_strpos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -6
Warning: mb_strpos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -20
Warning: mb_strpos(): Offset not contained in string in %s on line %d
bool(false)
------- stripos -----------
> Offset: 0
int(0)
> Offset: 3
int(4)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
Warning: stripos(): Offset not contained in string in %s on line %d
> Offset: -1
bool(false)
> Offset: -3
int(8)
> Offset: -6
int(8)
> Offset: -20
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
------- mb_stripos -----------
> Offset: 0
int(0)
> Offset: 3
int(4)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: mb_stripos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -1
Warning: mb_stripos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -3
Warning: mb_stripos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -6
Warning: mb_stripos(): Offset not contained in string in %s on line %d
bool(false)
> Offset: -20
Warning: mb_stripos(): Offset not contained in string in %s on line %d
bool(false)
------- strrpos -----------
> Offset: 0
int(8)
> Offset: 3
int(8)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: strrpos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
> Offset: -1
int(8)
> Offset: -3
int(8)
> Offset: -6
int(4)
> Offset: -20
Warning: strrpos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
------- mb_strrpos -----------
> Offset: 0
int(8)
> Offset: 3
int(8)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: mb_strrpos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
> Offset: -1
int(8)
> Offset: -3
int(8)
> Offset: -6
int(4)
> Offset: -20
Warning: mb_strrpos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
------- strripos -----------
> Offset: 0
int(8)
> Offset: 3
int(8)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: strripos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
> Offset: -1
int(8)
> Offset: -3
int(8)
> Offset: -6
int(4)
> Offset: -20
Warning: strripos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
------- mb_strripos -----------
> Offset: 0
int(8)
> Offset: 3
int(8)
> Offset: 6
int(8)
> Offset: 9
bool(false)
> Offset: 11
bool(false)
> Offset: 12
Warning: mb_strripos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)
> Offset: -1
int(8)
> Offset: -3
int(8)
> Offset: -6
int(4)
> Offset: -20
Warning: mb_strripos(): Offset is greater than the length of haystack string in %s on line %d
bool(false)

6
ext/standard/string.c

@ -1968,6 +1968,9 @@ PHP_FUNCTION(strpos)
ZEND_PARSE_PARAMETERS_END();
#endif
if (offset < 0) {
offset += (zend_long)ZSTR_LEN(haystack);
}
if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
@ -2018,6 +2021,9 @@ PHP_FUNCTION(stripos)
return;
}
if (offset < 0) {
offset += (zend_long)ZSTR_LEN(haystack);
}
if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;

20
ext/standard/tests/strings/stripos_basic2.phpt

@ -18,6 +18,9 @@ var_dump( stripos("Hello, World", "Hello", 0) );
var_dump( stripos("Hello, World", 'Hello', 1) );
var_dump( stripos('Hello, World', 'WORLD', 1) );
var_dump( stripos('Hello, World', "WoRld", 5) );
var_dump( stripos('Hello, World', "WoRld", -6) );
var_dump( stripos('Hello, World', "WoRld", -3) );
var_dump( stripos('Hello, World', "WoRld", -12) );
//heredoc string for haystack & needle, with various offsets
var_dump( stripos($heredoc_str, "Hello, World", 0) );
@ -25,12 +28,19 @@ var_dump( stripos($heredoc_str, 'Hello', 0) );
var_dump( stripos($heredoc_str, 'Hello', 1) );
var_dump( stripos($heredoc_str, $heredoc_str, 0) );
var_dump( stripos($heredoc_str, $heredoc_str, 1) );
var_dump( stripos($heredoc_str, $heredoc_str, -strlen($heredoc_str)) );
var_dump( stripos($heredoc_str, $heredoc_str, -strlen($heredoc_str)+1) );
//various offsets
var_dump( stripos("Hello, World", "o", 3) );
var_dump( stripos("Hello, World", "O", 5) );
var_dump( stripos("Hello, World", "o", 6) );
var_dump( stripos("Hello, World", "o", 10) );
var_dump( stripos("Hello, World", "o", -7) );
var_dump( stripos("Hello, World", "o", -8) );
var_dump( stripos("Hello, World", "o", -10) );
var_dump( stripos("Hello, World", "o", -4) );
var_dump( stripos("Hello, World", "o", -3) );
echo "*** Done ***";
?>
--EXPECTF--
@ -40,13 +50,23 @@ int(0)
bool(false)
int(7)
int(7)
int(7)
bool(false)
int(7)
int(0)
int(0)
bool(false)
int(0)
bool(false)
int(0)
bool(false)
int(4)
int(8)
int(8)
bool(false)
int(8)
int(4)
int(4)
int(8)
bool(false)
*** Done ***

15
ext/standard/tests/strings/stripos_error.phpt

@ -16,6 +16,13 @@ var_dump( stripos("String") );
echo "\n-- With more than expected number of arguments --";
var_dump( stripos("string", "String", 1, 'extra_arg') );
echo "\n-- Offset beyond the end of the string --";
var_dump( stripos("Hello World", "o", 12) );
echo "\n-- Offset before the start of the string --";
var_dump( stripos("Hello World", "o", -12) );
echo "*** Done ***";
?>
--EXPECTF--
@ -32,4 +39,12 @@ NULL
-- With more than expected number of arguments --
Warning: stripos() expects at most 3 parameters, 4 given in %s on line %d
NULL
-- Offset beyond the end of the string --
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Offset before the start of the string --
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
*** Done ***

6
ext/standard/tests/strings/stripos_variation14.phpt

@ -1,7 +1,5 @@
--TEST--
Test stripos() function : usage variations - unexpected inputs for 'offset' argument
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64-bit only");
--FILE--
<?php
/* Prototype : int stripos ( string $haystack, string $needle [, int $offset] );
@ -37,7 +35,7 @@ $offsets = array (
// float values
1.5,
-1.5,
1.5e10,
1.5e6,
1.6E-10,
.5,
@ -91,8 +89,6 @@ echo "*** Done ***";
-- Iteration 1 --
int(6)
-- Iteration 2 --
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 3 --

BIN
ext/standard/tests/strings/strpos.phpt

5
tests/lang/bug22592.phpt

@ -32,7 +32,8 @@ var_dump($result);
$e = $result[1] = $result[6];
var_dump($result);
var_dump($a, $b, $c, $d, $e);
$result[-1] = 'a';
$result[0] = $result[-4] = $result[-1] = 'a';
var_dump($result);
?>
--EXPECT--
string(5) "* *-*"
@ -50,4 +51,4 @@ string(1) "s"
string(1) "4"
string(1) "5"
string(1) "5"
[Illegal string offset: -1]
string(9) "a54s4a50a"
Loading…
Cancel
Save