From e7373cddaf809c2221c0167acae8568161d50d94 Mon Sep 17 00:00:00 2001 From: Moriyoshi Koizumi Date: Sat, 14 Feb 2009 07:33:41 +0000 Subject: [PATCH] - Fix Bug #45923 (mb_st[r]ripos() offset not handled correctly) # test still fails because of the difference of str[r]pos() behavior between 5.3 and 6.0. --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 2 +- ext/mbstring/mbstring.c | 48 +++++-- ext/mbstring/mbstring.h | 2 +- ext/mbstring/tests/bug45923.phpt | 202 +++++++++++++++++++++++++++ 4 files changed, 237 insertions(+), 17 deletions(-) create mode 100644 ext/mbstring/tests/bug45923.phpt diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index a2c117d2a3..907fa272b6 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -905,7 +905,7 @@ mbfl_strpos( } if (offset < 0) { - negative_offset = -offset-1; + negative_offset = -offset - pc.needle_len; offset = 0; } diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 268bbe73e4..7b5108545e 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -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); diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 4d2e0b7b31..af3e405b4e 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -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 index 0000000000..2d184ab019 --- /dev/null +++ b/ext/mbstring/tests/bug45923.phpt @@ -0,0 +1,202 @@ +--TEST-- +Bug #45923 (mb_st[r]ripos() offset not handled correctly) +--SKIPIF-- + +--INI-- +mbstring.internal_encoding=UTF-8 +--FILE-- + +--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) -- 2.40.0