From: Francois Laupretre Date: Tue, 5 Jan 2016 15:41:10 +0000 (+0100) Subject: mb_strpos()/mb_stripos(): Add support for negative offset X-Git-Tag: php-7.1.0alpha1~508 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0d9e7251ebfa28c25ed43619fe92c5ac3452e52;p=php mb_strpos()/mb_stripos(): Add support for negative offset --- diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index aba1607a6d..796c482865 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2262,7 +2262,7 @@ PHP_FUNCTION(mb_strlen) PHP_FUNCTION(mb_strpos) { int n, reverse = 0; - zend_long offset = 0; + zend_long offset = 0, slen; mbfl_string haystack, needle; char *enc_name = NULL; size_t enc_name_len, haystack_len, needle_len; @@ -2297,7 +2297,11 @@ PHP_FUNCTION(mb_strpos) } } - if (offset < 0 || offset > mbfl_strlen(&haystack)) { + slen = mbfl_strlen(&haystack); + if (offset < 0) { + offset += slen; + } + if (offset < 0 || offset > slen) { php_error_docref(NULL, E_WARNING, "Offset not contained in string"); RETURN_FALSE; } @@ -4877,6 +4881,9 @@ MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int break; } } else { + if (offset < 0) { + offset += (long)haystack_char_len; + } if (offset < 0 || offset > haystack_char_len) { php_error_docref(NULL, E_WARNING, "Offset not contained in string"); break; diff --git a/ext/mbstring/tests/bug45923.phpt b/ext/mbstring/tests/bug45923.phpt index 7819b94e13..41ffd70924 100644 --- a/ext/mbstring/tests/bug45923.phpt +++ b/ext/mbstring/tests/bug45923.phpt @@ -73,17 +73,11 @@ bool(false) 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) +int(8) > Offset: -6 - -Warning: mb_strpos(): Offset not contained in string in %s on line %d -bool(false) +int(8) > Offset: -20 Warning: mb_strpos(): Offset not contained in string in %s on line %d @@ -133,17 +127,11 @@ bool(false) 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) +int(8) > Offset: -6 - -Warning: mb_stripos(): Offset not contained in string in %s on line %d -bool(false) +int(8) > Offset: -20 Warning: mb_stripos(): Offset not contained in string in %s on line %d diff --git a/ext/mbstring/tests/mb_stripos.phpt b/ext/mbstring/tests/mb_stripos.phpt index 4ea8cfa6d6..8268872223 100644 --- a/ext/mbstring/tests/mb_stripos.phpt +++ b/ext/mbstring/tests/mb_stripos.phpt @@ -1,10 +1,7 @@ --TEST-- mb_stripos() --SKIPIF-- - + --FILE-- - +==DONE== --EXPECT-- +String len: 43 == POSITIVE OFFSET == 10 0 @@ -128,27 +152,41 @@ $r = mb_stripos($euc_jp, $t_obj, 'BAD_ENCODING'); 33 30 == NEGATIVE OFFSET == +34 +30 +33 +30 +0 +== INVALID OFFSET == ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET +ERR: Warning +OK_INVALID_OFFSET +ERR: Warning +OK_INVALID_OFFSET == OUT OF RANGE == OK_OUT_RANGE OK_OUT_RANGE OK_OUT_RANGE OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE == NON-EXISTENT == OK_STR OK_NEWLINE @@ -175,4 +213,4 @@ ERR: Warning OK_OBJECT ERR: Warning OK_BAD_ENCODING - +==DONE== diff --git a/ext/mbstring/tests/mb_stripos_variation3.phpt b/ext/mbstring/tests/mb_stripos_variation3.phpt index 21a1293786..69c4a9e53b 100644 --- a/ext/mbstring/tests/mb_stripos_variation3.phpt +++ b/ext/mbstring/tests/mb_stripos_variation3.phpt @@ -8,10 +8,9 @@ if (PHP_INT_SIZE != 8) die('skip 64-bit only'); ?> --FILE-- --FILE-- - +==DONE== --EXPECT-- +String len: 43 == POSITIVE OFFSET == 10 0 @@ -125,27 +152,41 @@ $r = mb_strpos($euc_jp, $t_obj, 'BAD_ENCODING'); 33 30 == NEGATIVE OFFSET == +34 +30 +33 +30 +0 +== INVALID OFFSET == +ERR: Warning +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET ERR: Warning -OK_NEGATIVE_OFFSET +OK_INVALID_OFFSET +ERR: Warning +OK_INVALID_OFFSET == OUT OF RANGE == OK_OUT_RANGE OK_OUT_RANGE OK_OUT_RANGE OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE +OK_OUT_RANGE == NON-EXISTENT == OK_STR OK_NEWLINE @@ -172,4 +213,4 @@ ERR: Warning OK_OBJECT ERR: Warning OK_BAD_ENCODING - +==DONE== diff --git a/ext/mbstring/tests/mb_strpos_variation3.phpt b/ext/mbstring/tests/mb_strpos_variation3.phpt index 8079a19021..f30b708183 100644 --- a/ext/mbstring/tests/mb_strpos_variation3.phpt +++ b/ext/mbstring/tests/mb_strpos_variation3.phpt @@ -51,45 +51,47 @@ $inputs = array( /*1*/ 0, 1, 12345, + -5, -2345, // float data -/*5*/ 10.5, - -10.5, +/*6*/ 10.5, + -5.5, + -100.5, 12.3456789000e10, 12.3456789000E-10, .5, // null data -/*10*/ NULL, +/*12*/ NULL, null, // boolean data -/*12*/ true, +/*14*/ true, false, TRUE, FALSE, // empty data -/*16*/ "", +/*18*/ "", '', // string data -/*18*/ "string", +/*20*/ "string", 'string', $heredoc, // object data -/*21*/ new classA(), +/*23*/ new classA(), // undefined data -/*22*/ @$undefined_var, +/*24*/ @$undefined_var, // unset data -/*23*/ @$unset_var, +/*25*/ @$unset_var, // resource variable -/*24*/ $fp +/*26*/ $fp ); // loop through each element of $inputs to check the behavior of mb_strpos() @@ -119,28 +121,28 @@ Warning: mb_strpos(): Offset not contained in string in %s on line %d bool(false) -- Iteration 4 -- - -Warning: mb_strpos(): Offset not contained in string in %s on line %d -bool(false) +int(8) -- Iteration 5 -- + +Warning: mb_strpos(): Offset not contained in string in %s on line %d bool(false) -- Iteration 6 -- - -Warning: mb_strpos(): Offset not contained in string in %s on line %d bool(false) -- Iteration 7 -- +int(8) + +-- Iteration 8 -- Warning: mb_strpos(): Offset not contained in string in %s on line %d bool(false) --- Iteration 8 -- -int(8) - -- Iteration 9 -- -int(8) + +Warning: mb_strpos(): Offset not contained in string in %s on line %d +bool(false) -- Iteration 10 -- int(8) @@ -161,42 +163,48 @@ int(8) int(8) -- Iteration 16 -- +int(8) + +-- Iteration 17 -- +int(8) + +-- Iteration 18 -- Warning: mb_strpos() expects parameter 3 to be integer, string given in %s on line %d NULL --- Iteration 17 -- +-- Iteration 19 -- Warning: mb_strpos() expects parameter 3 to be integer, string given in %s on line %d NULL --- Iteration 18 -- +-- Iteration 20 -- Warning: mb_strpos() expects parameter 3 to be integer, string given in %s on line %d NULL --- Iteration 19 -- +-- Iteration 21 -- Warning: mb_strpos() expects parameter 3 to be integer, string given in %s on line %d NULL --- Iteration 20 -- +-- Iteration 22 -- Warning: mb_strpos() expects parameter 3 to be integer, string given in %s on line %d NULL --- Iteration 21 -- +-- Iteration 23 -- Warning: mb_strpos() expects parameter 3 to be integer, object given in %s on line %d NULL --- Iteration 22 -- +-- Iteration 24 -- int(8) --- Iteration 23 -- +-- Iteration 25 -- int(8) --- Iteration 24 -- +-- Iteration 26 -- Warning: mb_strpos() expects parameter 3 to be integer, resource given in %s on line %d NULL diff --git a/ext/mbstring/tests/mb_strpos_variation5.phpt b/ext/mbstring/tests/mb_strpos_variation5.phpt index 7a9604abef..23bfa22b61 100644 --- a/ext/mbstring/tests/mb_strpos_variation5.phpt +++ b/ext/mbstring/tests/mb_strpos_variation5.phpt @@ -33,7 +33,7 @@ $needle_mb = base64_decode('44CC'); * mb_strpos should not be able to accept negative values as $offset. * 60 is larger than *BYTE* count for $string_mb */ -for ($i = -10; $i <= 60; $i += 10) { +for ($i = -30; $i <= 60; $i += 10) { echo "\n**-- Offset is: $i --**\n"; echo "-- ASCII String --\n"; var_dump(mb_strpos($string_ascii, $needle_ascii, $i)); @@ -47,7 +47,7 @@ echo "Done"; --EXPECTF-- *** Testing mb_strpos() : usage variations *** -**-- Offset is: -10 --** +**-- Offset is: -30 --** -- ASCII String -- Warning: mb_strpos(): Offset not contained in string in %s on line %d @@ -57,6 +57,18 @@ bool(false) Warning: mb_strpos(): Offset not contained in string in %s on line %d bool(false) +**-- Offset is: -20 --** +-- ASCII String -- +int(9) +--Multibyte String -- +int(9) + +**-- Offset is: -10 --** +-- ASCII String -- +int(20) +--Multibyte String -- +int(20) + **-- Offset is: 0 --** -- ASCII String -- int(9)