Skip to content

Commit 0154a5a

Browse files
committed
Use fast text conversion filters to implement php_mb_convert_encoding_ex
1 parent 8dddd3c commit 0154a5a

File tree

4 files changed

+12
-37
lines changed

4 files changed

+12
-37
lines changed

ext/mbstring/libmbfl/mbfl/mbfl_convert.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,9 @@ int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter)
348348
return 0;
349349
}
350350

351-
zend_string* mb_fast_convert(zend_string *str, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors)
351+
zend_string* mb_fast_convert(unsigned char *in, size_t in_len, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors)
352352
{
353353
uint32_t wchar_buf[128];
354-
unsigned char *in = (unsigned char*)ZSTR_VAL(str);
355-
size_t in_len = ZSTR_LEN(str);
356354
unsigned int state = 0;
357355

358356
mb_convert_buf buf;

ext/mbstring/libmbfl/mbfl/mbfl_convert.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ MBFLAPI extern int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter);
8181
MBFLAPI extern void mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src);
8282
MBFLAPI extern int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p);
8383

84-
MBFLAPI extern zend_string* mb_fast_convert(zend_string *str, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors);
84+
MBFLAPI extern zend_string* mb_fast_convert(unsigned char *in, size_t in_len, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors);
8585
MBFLAPI extern void mb_illegal_output(uint32_t bad_cp, mb_from_wchar_fn fn, mb_convert_buf* buf);
8686

8787
#endif /* MBFL_CONVERT_H */

ext/mbstring/mbstring.c

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,39 +2353,15 @@ static inline bool php_mb_is_no_encoding_utf8(enum mbfl_no_encoding no_enc)
23532353

23542354
MBSTRING_API char *php_mb_convert_encoding_ex(const char *input, size_t length, const mbfl_encoding *to_encoding, const mbfl_encoding *from_encoding, size_t *output_len)
23552355
{
2356-
mbfl_string string, result, *ret;
2357-
mbfl_buffer_converter *convd;
2358-
char *output = NULL;
2359-
2360-
if (output_len) {
2361-
*output_len = 0;
2362-
}
2356+
unsigned int num_errors = 0;
2357+
zend_string *result = mb_fast_convert((unsigned char*)input, length, from_encoding, to_encoding, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode), &num_errors);
23632358

2364-
/* initialize string */
2365-
string.encoding = from_encoding;
2366-
string.val = (unsigned char *)input;
2367-
string.len = length;
2368-
2369-
/* initialize converter */
2370-
convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);
2371-
/* If this assertion fails this means some memory allocation failure which is a bug */
2372-
ZEND_ASSERT(convd != NULL);
2359+
MBSTRG(illegalchars) += num_errors;
2360+
*output_len = ZSTR_LEN(result);
23732361

2374-
mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
2375-
mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
2376-
2377-
/* do it */
2378-
mbfl_string_init(&result);
2379-
ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
2380-
if (ret) {
2381-
if (output_len) {
2382-
*output_len = ret->len;
2383-
}
2384-
output = (char *)ret->val;
2385-
}
2386-
2387-
MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
2388-
mbfl_buffer_converter_delete(convd);
2362+
char *output = emalloc(ZSTR_LEN(result) + 1);
2363+
memcpy(output, ZSTR_VAL(result), ZSTR_LEN(result) + 1);
2364+
efree(result);
23892365
return output;
23902366
}
23912367
/* }}} */
@@ -2573,7 +2549,7 @@ PHP_FUNCTION(mb_convert_encoding)
25732549
const mbfl_encoding *from_encoding = from_encodings[0];
25742550
if (from_encoding->to_wchar && to_encoding->from_wchar) {
25752551
unsigned int num_errors = 0;
2576-
RETVAL_STR(mb_fast_convert(input_str, from_encoding, to_encoding, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode), &num_errors));
2552+
RETVAL_STR(mb_fast_convert((unsigned char*)ZSTR_VAL(input_str), ZSTR_LEN(input_str), from_encoding, to_encoding, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode), &num_errors));
25772553
MBSTRG(illegalchars) += num_errors;
25782554
goto out;
25792555
}

sapi/fuzzer/fuzzer-mbstring.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
5151
return 0;
5252
}
5353

54-
char *Result = php_mb_convert_encoding_ex((char *) Data, Size, ToEncoding, FromEncoding, NULL);
54+
size_t output_len;
55+
char *Result = php_mb_convert_encoding_ex((char *) Data, Size, ToEncoding, FromEncoding, &output_len);
5556
efree(Result);
5657
efree(ToEncodingName);
5758
efree(FromEncodingName);

0 commit comments

Comments
 (0)