Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion ext/mbstring/mbstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -2996,6 +2996,66 @@ PHP_FUNCTION(mb_strimwidth)
}
/* }}} */

static const enum mbfl_no_encoding php_mb_no_encoding_unicode_list[] = {
mbfl_no_encoding_utf8,
mbfl_no_encoding_utf8_docomo,
mbfl_no_encoding_utf8_kddi_a,
mbfl_no_encoding_utf8_kddi_b,
mbfl_no_encoding_utf8_sb,
mbfl_no_encoding_ucs4,
mbfl_no_encoding_ucs4be,
mbfl_no_encoding_ucs4le,
mbfl_no_encoding_utf32,
mbfl_no_encoding_utf32be,
mbfl_no_encoding_utf32le,
mbfl_no_encoding_ucs2,
mbfl_no_encoding_ucs2be,
mbfl_no_encoding_ucs2le,
mbfl_no_encoding_utf16,
mbfl_no_encoding_utf16be,
mbfl_no_encoding_utf16le
};

static inline int php_mb_is_no_encoding_unicode(enum mbfl_no_encoding no_enc)
{
int i;
int size = sizeof(php_mb_no_encoding_unicode_list)/sizeof(php_mb_no_encoding_unicode_list[0]);

for (i = 0; i < size; i++) {

if (no_enc == php_mb_no_encoding_unicode_list[i]) {
return 1;
}

}

return 0;
}

static const enum mbfl_no_encoding php_mb_no_encoding_utf8_list[] = {
mbfl_no_encoding_utf8,
mbfl_no_encoding_utf8_docomo,
mbfl_no_encoding_utf8_kddi_a,
mbfl_no_encoding_utf8_kddi_b,
mbfl_no_encoding_utf8_sb
};

static inline int php_mb_is_no_encoding_utf8(enum mbfl_no_encoding no_enc)
{
int i;
int size = sizeof(php_mb_no_encoding_utf8_list)/sizeof(php_mb_no_encoding_utf8_list[0]);

for (i = 0; i < size; i++) {

if (no_enc == php_mb_no_encoding_utf8_list[i]) {
return 1;
}

}

return 0;
}

/* {{{ MBSTRING_API char *php_mb_convert_encoding() */
MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len)
{
Expand Down Expand Up @@ -3066,7 +3126,28 @@ MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, co
return NULL;
}
mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));

if (string.no_encoding == MBSTRG(current_internal_encoding)->no_encoding) {
mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
} else if (php_mb_is_no_encoding_unicode(string.no_encoding) && php_mb_is_no_encoding_unicode(MBSTRG(current_internal_encoding)->no_encoding)) {

if (php_mb_is_no_encoding_utf8(string.no_encoding)) {

if (MBSTRG(current_filter_illegal_substchar) > 0xd7ff &&
0xe000 > MBSTRG(current_filter_illegal_substchar)
) {
mbfl_buffer_converter_illegal_substchar(convd, 0x3f);
} else {
mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
}

} else {
mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
}

} else {
mbfl_buffer_converter_illegal_substchar(convd, 0x3f);
}

/* do it */
ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
Expand Down
17 changes: 17 additions & 0 deletions ext/mbstring/tests/bug69086.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Request #69086 (enhancement for mb_convert_encoding)
--SKIPIF--
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
--FILE--
<?php
mb_substitute_character(0xfffd);
var_dump("?" === mb_convert_encoding("\x80", "Shift_JIS", "EUC-JP"));
mb_internal_encoding("UCS-4BE");
var_dump("\x00\x00\xff\xfd" === mb_convert_encoding("\x80", "UCS-4BE", "UTF-8"));
mb_substitute_character(0xd800);
var_dump("\x00\x00\x00\x3f" === mb_convert_encoding("\x80", "UCS-4BE", "UTF-8"));
?>
--EXPECT--
bool(true)
bool(true)
bool(true)