string. Previously non-string needles were interpreted as an ASCII code
point. An explicit call to chr() can be used to restore the previous
behavior.
+ . The needle argument for strpos(), strrpos(), stripos(), strripos(), strstr() and stristr() can now be empty.
. The 'salt' option of password_hash() is no longer supported. If the 'salt'
option is used a warning is generated, the provided salt is ignored, and a
generated salt is used instead.
ptrdiff_t off_p;
size_t off_s;
+ if (needle_len == 0) {
+ return p;
+ }
+
if (needle_len == 1) {
return (const char *)memchr(p, *needle, (end-p));
}
ptrdiff_t off_p;
size_t off_s;
+ if (needle_len == 0) {
+ return p;
+ }
+
if (needle_len == 1) {
return (const char *)zend_memrchr(haystack, *needle, (p - haystack));
}
Z_PARAM_BOOL(part)
ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- RETURN_FALSE;
- }
-
haystack_dup = estrndup(ZSTR_VAL(haystack), ZSTR_LEN(haystack));
orig_needle = estrndup(ZSTR_VAL(needle), ZSTR_LEN(needle));
found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), ZSTR_LEN(needle));
Z_PARAM_BOOL(part)
ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- RETURN_FALSE;
- }
-
found = php_memnstr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
if (found) {
RETURN_FALSE;
}
- if (!ZSTR_LEN(needle)) {
- php_error_docref(NULL, E_WARNING, "Empty needle");
- RETURN_FALSE;
- }
-
found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
ZSTR_VAL(needle), ZSTR_LEN(needle),
ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
RETURN_FALSE;
}
- if (ZSTR_LEN(needle) == 0 || ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
+ if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
RETURN_FALSE;
}
Finds position of last occurrence of a string within another string */
PHP_FUNCTION(strrpos)
{
+ zend_string *needle;
zend_string *haystack;
- char *needle;
- size_t needle_len;
zend_long offset = 0;
const char *p, *e, *found;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STR(haystack)
- Z_PARAM_STRING(needle, needle_len)
+ Z_PARAM_STR(needle)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
- if (ZSTR_LEN(haystack) == 0 || needle_len == 0) {
- RETURN_FALSE;
- }
-
if (offset >= 0) {
if ((size_t)offset > ZSTR_LEN(haystack)) {
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
+
p = ZSTR_VAL(haystack);
- if ((size_t)-offset < needle_len) {
+ if ((size_t)-offset < ZSTR_LEN(needle)) {
e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
} else {
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) + offset + needle_len;
+ e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) + offset + ZSTR_LEN(needle);
}
}
- if ((found = zend_memnrstr(p, needle, needle_len, e))) {
+ if ((found = zend_memnrstr(p, ZSTR_VAL(needle), ZSTR_LEN(needle), e))) {
RETURN_LONG(found - ZSTR_VAL(haystack));
}
Z_PARAM_LONG(offset)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
- if (ZSTR_LEN(haystack) == 0 || ZSTR_LEN(needle) == 0) {
- RETURN_FALSE;
- }
-
if (ZSTR_LEN(needle) == 1) {
/* Single character search can shortcut memcmps
Can also avoid tolower emallocs */
php_error_docref(NULL, E_WARNING, "Offset not contained in string");
RETURN_FALSE;
}
+
p = ZSTR_VAL(haystack_dup);
if ((size_t)-offset < ZSTR_LEN(needle)) {
e = ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack);
+++ /dev/null
---TEST--
-Bug #63943 (Bad warning text from strpos() on empty needle)
---FILE--
-<?php
-strpos("lllllll", '');
-?>
---EXPECTF--
-Warning: strpos(): Empty needle in %sbug63943.php on line %d
var_dump(stripos("0", false));
var_dump(stripos("1", true));
var_dump(stripos("\\\\a", "\\a"));
-
- echo "Done\n";
?>
+
+DONE
--EXPECT--
int(0)
int(5)
int(2)
int(0)
int(0)
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(0)
int(0)
bool(false)
bool(false)
+int(0)
bool(false)
-bool(false)
+int(0)
bool(false)
bool(false)
int(0)
bool(false)
int(0)
+int(0)
+int(0)
int(1)
-Done
+
+DONE
int(8)
bool(false)
-- Iteration 12 --
-bool(false)
-bool(false)
+int(0)
+int(11)
-- Iteration 13 --
-bool(false)
-bool(false)
+int(0)
+int(12)
-- Iteration 14 --
-bool(false)
-bool(false)
+int(0)
+int(13)
-- Iteration 15 --
-bool(false)
-bool(false)
+int(0)
+int(14)
-- Iteration 16 --
-bool(false)
-bool(false)
+int(0)
+int(15)
-- Iteration 17 --
int(10)
int(47)
echo "*** Done ***";
?>
---EXPECTF--
+--EXPECT--
*** Testing stripos() function with unexpected values for needle ***
-- Iteration 1 --
int(9)
-- Iteration 16 --
-bool(false)
+int(0)
-- Iteration 17 --
int(9)
-- Iteration 18 --
-bool(false)
+int(0)
-- Iteration 19 --
int(64)
-- Iteration 20 --
-bool(false)
+int(0)
-- Iteration 21 --
-bool(false)
+int(0)
-- Iteration 22 --
-bool(false)
+int(0)
-- Iteration 23 --
-bool(false)
+int(0)
-- Iteration 24 --
stripos() expects parameter 2 to be string, resource given
-- Iteration 25 --
-bool(false)
+int(0)
-- Iteration 26 --
-bool(false)
+int(0)
*** Done ***
int(0)
bool(false)
-- Iteration 16 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
int(0)
bool(false)
-- Iteration 18 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
int(0)
bool(false)
-- Iteration 20 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 21 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 22 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 23 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
stripos() expects parameter 1 to be string, resource given
stripos() expects parameter 1 to be string, resource given
-- Iteration 25 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 26 --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
int(10)
int(10)
-- Iteration 12 --
-bool(false)
-bool(false)
+int(0)
+int(11)
-- Iteration 13 --
-bool(false)
-bool(false)
+int(0)
+int(12)
-- Iteration 14 --
-bool(false)
-bool(false)
+int(0)
+int(13)
-- Iteration 15 --
-bool(false)
-bool(false)
+int(0)
+int(14)
-- Iteration 16 --
-bool(false)
-bool(false)
+int(0)
+int(15)
-- Iteration 17 --
int(14)
int(51)
int(14)
int(23)
int(23)
-bool(false)
+int(0)
int(7)
*** Done ***
--EXPECTF--
*** Testing stripos() function: with heredoc strings ***
-- With empty heredoc string --
-bool(false)
+int(0)
Warning: stripos(): Offset not contained in string in %s on line %d
bool(false)
-bool(false)
-bool(false)
+int(0)
+int(0)
*** Done ***
var_dump(stristr("tEsT sTrInG", "t S"));
var_dump(stristr("tEsT sTrInG", "g"));
var_dump(md5(stristr("te".chr(0)."st", chr(0))));
- var_dump(@stristr("", ""));
- var_dump(@stristr("a", ""));
- var_dump(@stristr("", "a"));
- var_dump(md5(@stristr("\\\\a\\", "\\a")));
+ var_dump(stristr("", ""));
+ var_dump(stristr("a", ""));
+ var_dump(stristr("", "a"));
+ var_dump(md5(stristr("\\\\a\\", "\\a")));
var_dump(stristr("tEsT sTrInG", " "));
?>
--EXPECTF--
string(8) "T sTrInG"
string(1) "G"
string(32) "7272696018bdeb2c9a3f8d01fc2a9273"
-bool(false)
-bool(false)
+string(0) ""
+string(1) "a"
bool(false)
string(32) "6ec19f52f0766c463f3bb240f4396913"
string(7) " sTrInG"
+++ /dev/null
---TEST--
-Test stristr() function : error conditions
---FILE--
-<?php
-
-/* Prototype: string stristr ( string $haystack , mixed $needle [, bool $before_needle ] )
- Description: Case-insensitive strstr()
-*/
-echo "*** Testing stristr() : error conditions ***\n";
-
-echo "\n-- Testing stristr() function with empty haystack --\n";
-var_dump( stristr(NULL, "") );
-
-echo "\n-- Testing stristr() function with empty needle --\n";
-var_dump( stristr("Hello World", "") );
-
-?>
-===DONE===
---EXPECTF--
-*** Testing stristr() : error conditions ***
-
--- Testing stristr() function with empty haystack --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
-
--- Testing stristr() function with empty needle --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
-===DONE===
?>
===DONE===
---EXPECTF--
+--EXPECT--
*** Testing stristr() function: with unexpected inputs for 'needle' argument ***
-- Iteration 1 --
bool(false)
-- Iteration 11 --
bool(false)
-- Iteration 12 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
-- Iteration 13 --
bool(false)
-- Iteration 14 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
-- Iteration 15 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
-- Iteration 16 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
-- Iteration 17 --
bool(false)
-- Iteration 18 --
stristr() expects parameter 2 to be string, resource given
-- Iteration 19 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
-- Iteration 20 --
-
-Warning: stristr(): Empty needle in %s on line %d
-bool(false)
+string(11) "Hello World"
===DONE===
--- /dev/null
+--TEST--
+Test strpos() function : usage variations - complex strings containing other than 7-bit chars
+--FILE--
+<?php
+$string = chr(0).chr(128).chr(129).chr(234).chr(235).chr(254).chr(255);
+$stringAsHex = bin2hex($string);
+echo "-- Positions of some chars in the string '$stringAsHex' are as follows --\n";
+echo bin2hex( chr(128) ) ." => ";
+var_dump( strpos($string, chr(128)) );
+echo bin2hex( chr(255) ) ." => ";
+var_dump( strpos($string, chr(255), 3) );
+echo bin2hex( chr(256) ) ." => ";
+var_dump( strpos($string, chr(256)) );
+?>
+
+DONE
+--EXPECT--
+-- Positions of some chars in the string '008081eaebfeff' are as follows --
+80 => int(1)
+ff => int(6)
+00 => int(0)
+
+DONE
var_dump(strripos("te".chr(0)."st", chr(0)));
var_dump(strripos("tEst", "test"));
var_dump(strripos("teSt", "test"));
- var_dump(@strripos("foo", "f", 1));
- var_dump(@strripos("", ""));
- var_dump(@strripos("a", ""));
- var_dump(@strripos("", "a"));
- var_dump(@strripos("\\\\a", "\\a"));
+ var_dump(strripos("foo", "f", 1));
+ var_dump(strripos("", ""));
+ var_dump(strripos("a", ""));
+ var_dump(strripos("", "a"));
+ var_dump(strripos("\\\\a", "\\a"));
?>
--EXPECT--
int(5)
int(0)
int(0)
bool(false)
-bool(false)
-bool(false)
+int(0)
+int(1)
bool(false)
int(1)
bool(false)
int(8)
-- Iteration 12 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(44)
+int(44)
+int(44)
+int(43)
-- Iteration 13 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(44)
+int(44)
+int(44)
+int(43)
-- Iteration 14 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(44)
+int(44)
+int(44)
+int(43)
-- Iteration 15 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(44)
+int(44)
+int(44)
+int(43)
-- Iteration 16 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(44)
+int(44)
+int(44)
+int(43)
-- Iteration 17 --
int(43)
int(43)
bool(false)
int(10)
-- Iteration 12 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(54)
+int(54)
+int(54)
+int(53)
-- Iteration 13 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(54)
+int(54)
+int(54)
+int(53)
-- Iteration 14 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(54)
+int(54)
+int(54)
+int(53)
-- Iteration 15 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(54)
+int(54)
+int(54)
+int(53)
-- Iteration 16 --
-bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(54)
+int(54)
+int(54)
+int(53)
-- Iteration 17 --
int(53)
int(53)
-- Multi line strings with no offset --
int(18)
int(31)
-bool(false)
+int(63)
int(55)
===DONE===
--- /dev/null
+--TEST--
+Test strrpos() function : usage variations - negative offset with empty needle
+--FILE--
+<?php
+$haystack = "Hello,\t\n\0\n $&!#%()*<=>?@hello123456he \x234 \101 ";
+
+var_dump(strlen($haystack));
+
+var_dump( strripos($haystack, "", -1) );
+var_dump( strripos($haystack, "", -10) );
+var_dump( strripos($haystack, "", -26) );
+var_dump( strripos($haystack, "", -44) );
+?>
+
+DONE
+--EXPECT--
+int(44)
+int(43)
+int(34)
+int(18)
+int(0)
+
+DONE
var_dump(strrpos("te".chr(0)."st", chr(0)));
var_dump(strrpos("tEst", "test"));
var_dump(strrpos("teSt", "test"));
- var_dump(@strrpos("foo", "f", 1));
- var_dump(@strrpos("", ""));
- var_dump(@strrpos("a", ""));
- var_dump(@strrpos("", "a"));
- var_dump(@strrpos("\\\\a", "\\a"));
+ var_dump(strrpos("foo", "f", 1));
+ var_dump(strrpos("", ""));
+ var_dump(strrpos("a", ""));
+ var_dump(strrpos("", "a"));
+ var_dump(strrpos("\\\\a", "\\a"));
?>
--EXPECT--
int(5)
bool(false)
bool(false)
bool(false)
-bool(false)
-bool(false)
+int(0)
+int(1)
bool(false)
int(1)
int(8)
bool(false)
-- Iteration 12 --
-bool(false)
-bool(false)
+int(44)
+int(44)
-- Iteration 13 --
-bool(false)
-bool(false)
+int(44)
+int(44)
-- Iteration 14 --
-bool(false)
-bool(false)
+int(44)
+int(44)
-- Iteration 15 --
-bool(false)
-bool(false)
+int(44)
+int(44)
-- Iteration 16 --
-bool(false)
-bool(false)
+int(44)
+int(44)
-- Iteration 17 --
int(43)
int(43)
-- Iteration 15 --
int(41)
-- Iteration 16 --
-bool(false)
+int(87)
-- Iteration 17 --
int(41)
-- Iteration 18 --
-bool(false)
+int(87)
-- Iteration 19 --
int(64)
-- Iteration 20 --
-bool(false)
+int(87)
-- Iteration 21 --
-bool(false)
+int(87)
-- Iteration 22 --
-bool(false)
+int(87)
-- Iteration 23 --
-bool(false)
+int(87)
-- Iteration 24 --
strrpos() expects parameter 2 to be string, resource given
-- Iteration 25 --
-bool(false)
+int(87)
-- Iteration 26 --
-bool(false)
+int(87)
*** Done ***
echo "*** Done ***";
?>
---EXPECT--
+--EXPECTF--
*** Testing strrpos() function with unexpected values for haystack and needle ***
-- Iteration 1 --
int(0)
int(0)
bool(false)
-- Iteration 16 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 17 --
int(0)
bool(false)
-- Iteration 18 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 19 --
int(0)
bool(false)
-- Iteration 20 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 21 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 22 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 23 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 24 --
strrpos() expects parameter 1 to be string, resource given
strrpos() expects parameter 1 to be string, resource given
-- Iteration 25 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-- Iteration 26 --
-bool(false)
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
*** Done ***
--- /dev/null
+--TEST--
+Test strrpos() function : usage variations - negative offset with empty needle
+--FILE--
+<?php
+$haystack = "Hello,\t\n\0\n $&!#%()*<=>?@hello123456he \x234 \101 ";
+
+var_dump(strlen($haystack));
+
+var_dump( strrpos($haystack, "", -1) );
+var_dump( strrpos($haystack, "", -10) );
+var_dump( strrpos($haystack, "", -26) );
+var_dump( strrpos($haystack, "", -44) );
+?>
+
+DONE
+--EXPECT--
+int(44)
+int(43)
+int(34)
+int(18)
+int(0)
+
+DONE
int(10)
int(10)
-- Iteration 12 --
-bool(false)
-bool(false)
+int(54)
+int(54)
-- Iteration 13 --
-bool(false)
-bool(false)
+int(54)
+int(54)
-- Iteration 14 --
-bool(false)
-bool(false)
+int(54)
+int(54)
-- Iteration 15 --
-bool(false)
-bool(false)
+int(54)
+int(54)
-- Iteration 16 --
-bool(false)
-bool(false)
+int(54)
+int(54)
-- Iteration 17 --
int(53)
int(53)
int(44)
int(44)
int(44)
-bool(false)
+int(63)
int(55)
*** Done ***
echo "*** Done ***";
?>
---EXPECT--
+--EXPECTF--
*** Testing strrpos() function: with heredoc strings ***
-- With empty heredoc string --
+int(0)
+
+Warning: strrpos(): Offset not contained in string in %s on line %d
bool(false)
-bool(false)
-bool(false)
-bool(false)
+int(0)
+int(0)
*** Done ***
--- /dev/null
+--TEST--
+Test strstr() function : usage variations - complex strings containing other than 7-bit chars
+--FILE--
+<?php
+$string = chr(0).chr(128).chr(129).chr(234).chr(235).chr(254).chr(255);
+$stringAsHex = bin2hex($string);
+echo "-- Positions of some chars in the string '$stringAsHex' are as follows --\n";
+echo bin2hex( chr(128) ) ." => ";
+var_dump( bin2hex( strstr($string, chr(128) ) ) );
+echo bin2hex( chr(255) ) ." => ";
+var_dump( bin2hex( strstr($string, chr(255) ) ) );
+echo bin2hex( chr(256) ) ." => ";
+var_dump( bin2hex( strstr($string, chr(256) ) ) );
+?>
+
+DONE
+--EXPECT--
+-- Positions of some chars in the string '008081eaebfeff' are as follows --
+80 => string(12) "8081eaebfeff"
+ff => string(2) "ff"
+00 => string(14) "008081eaebfeff"
+
+DONE