]> granicus.if.org Git - php/commitdiff
- Fix Bug #45923 (mb_st[r]ripos() offset not handled correctly)
authorMoriyoshi Koizumi <moriyoshi@php.net>
Sat, 14 Feb 2009 07:33:41 +0000 (07:33 +0000)
committerMoriyoshi Koizumi <moriyoshi@php.net>
Sat, 14 Feb 2009 07:33:41 +0000 (07:33 +0000)
# test still fails because of the difference of str[r]pos() behavior between 5.3 and 6.0.

ext/mbstring/libmbfl/mbfl/mbfilter.c
ext/mbstring/mbstring.c
ext/mbstring/mbstring.h
ext/mbstring/tests/bug45923.phpt [new file with mode: 0644]

index a2c117d2a300dd36a5d2d9714d0af9afa2d0c75b..907fa272b61274a78baa60e60a396168d20cdd57 100644 (file)
@@ -905,7 +905,7 @@ mbfl_strpos(
        }
 
        if (offset < 0) {
-               negative_offset = -offset-1;
+               negative_offset = -offset - pc.needle_len;
                offset = 0;
        }
 
index 268bbe73e42fab8e68d41172543952181cd46f25..7b5108545e42edfacaa2cc15224a962a8399250f 100644 (file)
@@ -2075,8 +2075,8 @@ PHP_FUNCTION(mb_strpos)
                }
        }
 
-       if (offset < 0 || (unsigned long)offset > haystack.len) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string.");
+       if (offset < 0 || offset > mbfl_strlen(&haystack)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string");
                RETURN_FALSE;
        }
        if (needle.len == 0) {
@@ -2092,17 +2092,17 @@ PHP_FUNCTION(mb_strpos)
                case 1:
                        break;
                case 2:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Needle has not positive length.");
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Needle has not positive length");
                        break;
                case 4:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding or conversion error.");
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding or conversion error");
                        break;
                case 8:
-                       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Argument is empty.");
+                       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Argument is empty");
                        break;
                default:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error in mb_strpos.");
-                       break;                  
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error in mb_strpos");
+                       break;
                }
                RETVAL_FALSE;
        }
@@ -2188,6 +2188,16 @@ PHP_FUNCTION(mb_strrpos)
        if (needle.len <= 0) {
                RETURN_FALSE;
        }
+
+       {
+               int haystack_char_len = mbfl_strlen(&haystack);
+               if ((offset > 0 && offset > haystack_char_len) ||
+                       (offset < 0 && -offset > haystack_char_len)) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
+                       RETURN_FALSE;
+               }
+       }
+
        n = mbfl_strpos(&haystack, &needle, offset, 1);
        if (n >= 0) {
                RETVAL_LONG(n);
@@ -2242,10 +2252,6 @@ PHP_FUNCTION(mb_strripos)
                RETURN_FALSE;
        }
 
-       if ((unsigned int)offset > haystack.len) {
-               RETURN_FALSE;
-       }
-
        n = php_mb_stripos(1, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, offset, from_encoding TSRMLS_CC);
 
        if (n >= 0) {
@@ -4636,7 +4642,7 @@ MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length
 
 /* {{{ MBSTRING_API int php_mb_stripos()
  */
-MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, unsigned int offset, const char *from_encoding TSRMLS_DC)
+MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, long offset, const char *from_encoding TSRMLS_DC)
 {
        int n;
        mbfl_string haystack, needle;
@@ -4679,9 +4685,21 @@ MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int
                        break;
                }
 
-               if (offset < 0 || offset > haystack.len) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string.");
-                       break;
+               {
+                       int haystack_char_len = mbfl_strlen(&haystack);
+                       if (mode) {
+                               if ((offset > 0 && offset > haystack_char_len) ||
+                                       (offset < 0 && -offset > haystack_char_len)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
+                                       break;
+                               }
+                       } else {
+                               if (offset < 0 || offset > haystack_char_len) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string");
+                                       break;
+                               }
+                       }
                }
 
                n = mbfl_strpos(&haystack, &needle, offset, mode);
index 4d2e0b7b310dd89aa57bce42f1713b9b898e08c3..af3e405b4ef2d43a8ee45e363bfb9faf4d66ae8c 100644 (file)
@@ -157,7 +157,7 @@ MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, co
 
 MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC);
 
-MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, unsigned int offset, const char *from_encoding TSRMLS_DC);
+MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, long offset, const char *from_encoding TSRMLS_DC);
 
 ZEND_BEGIN_MODULE_GLOBALS(mbstring)
        enum mbfl_no_language language;
diff --git a/ext/mbstring/tests/bug45923.phpt b/ext/mbstring/tests/bug45923.phpt
new file mode 100644 (file)
index 0000000..2d184ab
--- /dev/null
@@ -0,0 +1,202 @@
+--TEST--
+Bug #45923 (mb_st[r]ripos() offset not handled correctly)
+--SKIPIF--
+<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
+--INI--
+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));
+
+?>
+--EXPECTF--
+int(0)
+int(4)
+int(8)
+bool(false)
+bool(false)
+
+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)
+
+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)
+int(0)
+int(4)
+int(8)
+bool(false)
+bool(false)
+
+Warning: mb_strpos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_strpos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_strpos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_strpos(): Offset not contained in string in %s on line %d
+bool(false)
+int(0)
+int(4)
+int(8)
+bool(false)
+bool(false)
+
+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)
+
+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)
+int(0)
+int(4)
+int(8)
+bool(false)
+bool(false)
+
+Warning: mb_stripos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_stripos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_stripos(): Offset not contained in string in %s on line %d
+bool(false)
+
+Warning: mb_stripos(): Offset not contained in string in %s on line %d
+bool(false)
+int(8)
+int(8)
+int(8)
+bool(false)
+bool(false)
+
+Warning: strrpos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+int(8)
+int(8)
+int(4)
+int(8)
+int(8)
+int(8)
+bool(false)
+bool(false)
+
+Warning: mb_strrpos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+int(8)
+int(8)
+int(4)
+int(8)
+int(8)
+int(8)
+bool(false)
+bool(false)
+
+Warning: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+int(8)
+int(8)
+int(4)
+int(8)
+int(8)
+int(8)
+bool(false)
+bool(false)
+
+Warning: mb_strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+int(8)
+int(8)
+int(4)