mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fixed bug #76319
While at it, also make sure that mbstring case conversion takes into account the specified substitution character and substitution mode.
This commit is contained in:
parent
3382424903
commit
9d63f4dec1
2
NEWS
2
NEWS
@ -105,6 +105,8 @@ PHP NEWS
|
||||
. Fixed bug #73528 (Crash in zif_mb_send_mail). (Nikita)
|
||||
. Fixed bug #74929 (mbstring functions version 7.1.1 are slow compared to 5.3
|
||||
on Windows). (Nikita)
|
||||
. Fixed bug #76319 (mb_strtolower with invalid UTF-8 causes segmentation
|
||||
fault). (Nikita)
|
||||
. Update to Oniguruma 6.8.1. (cmb)
|
||||
|
||||
- ODBC:
|
||||
|
@ -3252,6 +3252,14 @@ PHP_FUNCTION(mb_convert_encoding)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static char *mbstring_convert_case(
|
||||
int case_mode, const char *str, size_t str_len, size_t *ret_len,
|
||||
const mbfl_encoding *enc) {
|
||||
return php_unicode_convert_case(
|
||||
case_mode, str, str_len, ret_len, enc,
|
||||
MBSTRG(current_filter_illegal_mode), MBSTRG(current_filter_illegal_substchar));
|
||||
}
|
||||
|
||||
/* {{{ proto string mb_convert_case(string sourcestring, int mode [, string encoding])
|
||||
Returns a case-folded version of sourcestring */
|
||||
PHP_FUNCTION(mb_convert_case)
|
||||
@ -3280,7 +3288,7 @@ PHP_FUNCTION(mb_convert_case)
|
||||
return;
|
||||
}
|
||||
|
||||
newstr = php_unicode_convert_case(case_mode, str, str_len, &ret_len, enc);
|
||||
newstr = mbstring_convert_case(case_mode, str, str_len, &ret_len, enc);
|
||||
|
||||
if (newstr) {
|
||||
// TODO: avoid reallocation ???
|
||||
@ -3312,7 +3320,7 @@ PHP_FUNCTION(mb_strtoupper)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
newstr = php_unicode_convert_case(PHP_UNICODE_CASE_UPPER, str, str_len, &ret_len, enc);
|
||||
newstr = mbstring_convert_case(PHP_UNICODE_CASE_UPPER, str, str_len, &ret_len, enc);
|
||||
|
||||
if (newstr) {
|
||||
// TODO: avoid reallocation ???
|
||||
@ -3346,7 +3354,7 @@ PHP_FUNCTION(mb_strtolower)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
newstr = php_unicode_convert_case(PHP_UNICODE_CASE_LOWER, str, str_len, &ret_len, enc);
|
||||
newstr = mbstring_convert_case(PHP_UNICODE_CASE_LOWER, str, str_len, &ret_len, enc);
|
||||
|
||||
if (newstr) {
|
||||
// TODO: avoid reallocation ???
|
||||
@ -5172,7 +5180,7 @@ MBSTRING_API size_t php_mb_stripos(int mode, const char *old_haystack, size_t ol
|
||||
* offsets otherwise. */
|
||||
|
||||
size_t len = 0;
|
||||
haystack.val = (unsigned char *)php_unicode_convert_case(PHP_UNICODE_CASE_FOLD_SIMPLE, (char *)old_haystack, old_haystack_len, &len, enc);
|
||||
haystack.val = (unsigned char *)mbstring_convert_case(PHP_UNICODE_CASE_FOLD_SIMPLE, (char *)old_haystack, old_haystack_len, &len, enc);
|
||||
haystack.len = len;
|
||||
|
||||
if (!haystack.val) {
|
||||
@ -5183,7 +5191,7 @@ MBSTRING_API size_t php_mb_stripos(int mode, const char *old_haystack, size_t ol
|
||||
break;
|
||||
}
|
||||
|
||||
needle.val = (unsigned char *)php_unicode_convert_case(PHP_UNICODE_CASE_FOLD_SIMPLE, (char *)old_needle, old_needle_len, &len, enc);
|
||||
needle.val = (unsigned char *)mbstring_convert_case(PHP_UNICODE_CASE_FOLD_SIMPLE, (char *)old_needle, old_needle_len, &len, enc);
|
||||
needle.len = len;
|
||||
|
||||
if (!needle.val) {
|
||||
|
@ -312,6 +312,14 @@ static int convert_case_filter(int c, void *void_data)
|
||||
struct convert_case_data *data = (struct convert_case_data *) void_data;
|
||||
unsigned out[3];
|
||||
unsigned len, i;
|
||||
|
||||
/* Handle invalid characters early, as we assign special meaning to
|
||||
* codepoints above 0xffffff. */
|
||||
if (UNEXPECTED(c > 0xffffff)) {
|
||||
(*data->next_filter->filter_function)(c, data->next_filter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (data->case_mode) {
|
||||
case PHP_UNICODE_CASE_UPPER_SIMPLE:
|
||||
out[0] = php_unicode_toupper_simple(c, data->no_encoding);
|
||||
@ -376,7 +384,7 @@ static int convert_case_filter(int c, void *void_data)
|
||||
|
||||
MBSTRING_API char *php_unicode_convert_case(
|
||||
int case_mode, const char *srcstr, size_t srclen, size_t *ret_len,
|
||||
const mbfl_encoding *src_encoding)
|
||||
const mbfl_encoding *src_encoding, int illegal_mode, int illegal_substchar)
|
||||
{
|
||||
struct convert_case_data data;
|
||||
mbfl_convert_filter *from_wchar, *to_wchar;
|
||||
@ -403,6 +411,11 @@ MBSTRING_API char *php_unicode_convert_case(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
to_wchar->illegal_mode = illegal_mode;
|
||||
to_wchar->illegal_substchar = illegal_substchar;
|
||||
from_wchar->illegal_mode = illegal_mode;
|
||||
from_wchar->illegal_substchar = illegal_substchar;
|
||||
|
||||
data.next_filter = from_wchar;
|
||||
data.no_encoding = src_encoding->no_encoding;
|
||||
data.case_mode = case_mode;
|
||||
|
@ -87,8 +87,8 @@ MBSTRING_API int php_unicode_is_prop(unsigned long code, ...);
|
||||
MBSTRING_API int php_unicode_is_prop1(unsigned long code, int prop);
|
||||
|
||||
MBSTRING_API char *php_unicode_convert_case(
|
||||
int case_mode, const char *srcstr, size_t srclen, size_t *retlen,
|
||||
const mbfl_encoding *src_encoding);
|
||||
int case_mode, const char *srcstr, size_t srclen, size_t *ret_len,
|
||||
const mbfl_encoding *src_encoding, int illegal_mode, int illegal_substchar);
|
||||
|
||||
#define PHP_UNICODE_CASE_UPPER 0
|
||||
#define PHP_UNICODE_CASE_LOWER 1
|
||||
|
9
ext/mbstring/tests/bug76319.phpt
Normal file
9
ext/mbstring/tests/bug76319.phpt
Normal file
@ -0,0 +1,9 @@
|
||||
--TEST--
|
||||
Bug #76319: mb_strtolower with invalid UTF-8 causes segmentation fault
|
||||
--FILE--
|
||||
<?php
|
||||
mb_substitute_character(0xFFFD);
|
||||
var_dump(mb_strtolower("a\xA1", 'UTF-8'));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "a<>"
|
Loading…
Reference in New Issue
Block a user