From: Nikita Popov Date: Thu, 7 May 2020 08:45:49 +0000 (+0200) Subject: Only allow "pass" as input/output encoding X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=226d9dd30adb245303a4437035374c825671ab76;p=php Only allow "pass" as input/output encoding "pass" is not a real encoding, it just means "don't perform any conversion". Using it as an internal encoding or passing it to any of the mbstring() function will not work (and on master commonly assert). --- diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c index be861629d0..4feaadd542 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c @@ -115,7 +115,6 @@ static const mbfl_encoding *mbfl_encoding_ptr_list[] = { - &mbfl_encoding_pass, &mbfl_encoding_wchar, &mbfl_encoding_byte2be, &mbfl_encoding_byte2le, diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index e105e8638d..02a4aeba00 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -279,12 +279,21 @@ static const mbfl_encoding *php_mb_get_encoding(zend_string *encoding_name, uint } } +static const mbfl_encoding *php_mb_get_encoding_or_pass(const char *encoding_name) { + if (strcmp(encoding_name, "pass") == 0) { + return &mbfl_encoding_pass; + } + + return mbfl_name2encoding(encoding_name); +} + /* {{{ static int php_mb_parse_encoding_list() * Return FAILURE if input contains any illegal encoding, otherwise SUCCESS. * Emits a ValueError in function context and a warning in INI context, in INI context arg_num must be 0. */ static int php_mb_parse_encoding_list(const char *value, size_t value_length, - const mbfl_encoding ***return_list, size_t *return_size, int persistent, uint32_t arg_num) + const mbfl_encoding ***return_list, size_t *return_size, int persistent, uint32_t arg_num, + zend_bool allow_pass_encoding) { if (value == NULL || value_length == 0) { *return_list = NULL; @@ -346,7 +355,8 @@ static int php_mb_parse_encoding_list(const char *value, size_t value_length, } } } else { - const mbfl_encoding *encoding = mbfl_name2encoding(p1); + const mbfl_encoding *encoding = + allow_pass_encoding ? php_mb_get_encoding_or_pass(p1) : mbfl_name2encoding(p1); if (!encoding) { /* Called from an INI setting modification */ if (arg_num == 0) { @@ -512,7 +522,10 @@ static size_t php_mb_zend_encoding_converter(unsigned char **to, size_t *to_leng static int php_mb_zend_encoding_list_parser(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, int persistent) { - return php_mb_parse_encoding_list(encoding_list, encoding_list_len, (const mbfl_encoding ***)return_list, return_size, persistent, 0); + return php_mb_parse_encoding_list( + encoding_list, encoding_list_len, + (const mbfl_encoding ***)return_list, return_size, + persistent, /* arg_num */ 0, /* allow_pass_encoding */ 1); } static const zend_encoding *php_mb_zend_internal_encoding_getter(void) @@ -805,7 +818,7 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) return SUCCESS; } - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, 1, 0) || size == 0) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &list, &size, /* persistent */ 1, /* arg_num */ 0, /* allow_pass_encoding */ 0) || size == 0) { return FAILURE; } @@ -821,7 +834,7 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) static int _php_mb_ini_mbstring_http_input_set(const char *new_value, size_t new_value_length) { const mbfl_encoding **list; size_t size; - if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1, 0) || size == 0) { + if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, /* persistent */ 1, /* arg_num */ 0, /* allow_pass_encoding */ 1) || size == 0) { return FAILURE; } if (MBSTRG(http_input_list)) { @@ -852,7 +865,7 @@ static PHP_INI_MH(OnUpdate_mbstring_http_input) /* }}} */ static int _php_mb_ini_mbstring_http_output_set(const char *new_value) { - const mbfl_encoding *encoding = mbfl_name2encoding(new_value); + const mbfl_encoding *encoding = php_mb_get_encoding_or_pass(new_value); if (!encoding) { return FAILURE; } @@ -1446,7 +1459,7 @@ PHP_FUNCTION(mb_http_output) ZEND_ASSERT(MBSTRG(current_http_output_encoding)); RETURN_STRING(MBSTRG(current_http_output_encoding)->name); } else { - encoding = mbfl_name2encoding(name); + encoding = php_mb_get_encoding_or_pass(name); if (!encoding) { zend_argument_value_error(1, "must be a valid encoding, \"%s\" given", name); RETURN_THROWS(); @@ -1489,7 +1502,7 @@ PHP_FUNCTION(mb_detect_order) RETURN_THROWS(); } } else { - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(order_str), ZSTR_LEN(order_str), &list, &size, 0, 1)) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(order_str), ZSTR_LEN(order_str), &list, &size, /* persistent */ 0, /* arg_num */ 1, /* allow_pass_encoding */ 0)) { RETURN_THROWS(); } } @@ -2620,7 +2633,8 @@ PHP_FUNCTION(mb_convert_encoding) free_from_encodings = 1; } else if (from_encodings_str) { if (php_mb_parse_encoding_list(ZSTR_VAL(from_encodings_str), ZSTR_LEN(from_encodings_str), - &from_encodings, &num_from_encodings, 0, 3) == FAILURE) { + &from_encodings, &num_from_encodings, + /* persistent */ 0, /* arg_num */ 3, /* allow_pass_encoding */ 0) == FAILURE) { RETURN_THROWS(); } free_from_encodings = 1; @@ -2799,7 +2813,7 @@ PHP_FUNCTION(mb_detect_encoding) } free_elist = 1; } else if (encoding_str) { - if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, 0, 2)) { + if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, /* persistent */ 0, /* arg_num */ 2, /* allow_pass_encoding */ 0)) { RETURN_THROWS(); } free_elist = 1; @@ -3189,7 +3203,7 @@ PHP_FUNCTION(mb_convert_variables) RETURN_THROWS(); } } else { - if (php_mb_parse_encoding_list(ZSTR_VAL(from_enc_str), ZSTR_LEN(from_enc_str), &elist, &elistsz, 0, 2) == FAILURE) { + if (php_mb_parse_encoding_list(ZSTR_VAL(from_enc_str), ZSTR_LEN(from_enc_str), &elist, &elistsz, /* persistent */ 0, /* arg_num */ 2, /* allow_pass_encoding */ 0) == FAILURE) { RETURN_THROWS(); } } @@ -4096,10 +4110,6 @@ PHP_FUNCTION(mb_check_encoding) if (!encoding) { RETURN_THROWS(); } - if (encoding == &mbfl_encoding_pass) { - zend_value_error("mb_check_encoding() does not support the \"pass\" encoding"); - RETURN_THROWS(); - } if (input_ht) { if (!php_mb_check_encoding_recursive(input_ht, encoding)) { diff --git a/ext/mbstring/tests/mb_check_encoding_invalid_encodings.phpt b/ext/mbstring/tests/mb_check_encoding_invalid_encodings.phpt index 80e99ce3a1..a2d9b1cbfb 100644 --- a/ext/mbstring/tests/mb_check_encoding_invalid_encodings.phpt +++ b/ext/mbstring/tests/mb_check_encoding_invalid_encodings.phpt @@ -38,5 +38,5 @@ Using "BAD" as encoding mb_check_encoding(): Argument #2 ($encoding) must be a valid encoding, "BAD" given mb_check_encoding(): Argument #2 ($encoding) must be a valid encoding, "BAD" given Using "pass" as encoding -mb_check_encoding() does not support the "pass" encoding -mb_check_encoding() does not support the "pass" encoding +mb_check_encoding(): Argument #2 ($encoding) must be a valid encoding, "pass" given +mb_check_encoding(): Argument #2 ($encoding) must be a valid encoding, "pass" given diff --git a/ext/mbstring/tests/mb_chr.phpt b/ext/mbstring/tests/mb_chr.phpt index fb917371a0..06061dcfc3 100644 --- a/ext/mbstring/tests/mb_chr.phpt +++ b/ext/mbstring/tests/mb_chr.phpt @@ -52,7 +52,7 @@ bool(true) bool(true) bool(true) mb_chr(): Argument #2 ($encoding) must be a valid encoding, "typo" given -mb_chr() does not support the "pass" encoding +mb_chr(): Argument #2 ($encoding) must be a valid encoding, "pass" given mb_chr() does not support the "JIS" encoding mb_chr() does not support the "CP50222" encoding mb_chr() does not support the "UTF-7" encoding diff --git a/ext/mbstring/tests/mb_http_input.phpt b/ext/mbstring/tests/mb_http_input.phpt index 586a7d094d..aa65097597 100644 --- a/ext/mbstring/tests/mb_http_input.phpt +++ b/ext/mbstring/tests/mb_http_input.phpt @@ -3,47 +3,26 @@ mb_http_input() --SKIPIF-- --POST-- a=ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê --GET-- b=ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +--INI-- +mbstring.encoding_translation=1 +input_encoding=latin1 --FILE-- --EXPECT-- -ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê -ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê -OK +ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +string(10) "ISO-8859-1" diff --git a/ext/mbstring/tests/mb_http_input_pass.phpt b/ext/mbstring/tests/mb_http_input_pass.phpt new file mode 100644 index 0000000000..1c9cb93cd7 --- /dev/null +++ b/ext/mbstring/tests/mb_http_input_pass.phpt @@ -0,0 +1,28 @@ +--TEST-- +mb_http_input() with pass encoding +--SKIPIF-- + +--POST-- +a=ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +--GET-- +b=ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +--INI-- +mbstring.encoding_translation=1 +input_encoding=pass +--FILE-- + +--EXPECT-- +ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê +string(4) "pass" diff --git a/ext/mbstring/tests/mb_ord.phpt b/ext/mbstring/tests/mb_ord.phpt index 56e8d4a814..8785a29dfc 100644 --- a/ext/mbstring/tests/mb_ord.phpt +++ b/ext/mbstring/tests/mb_ord.phpt @@ -58,7 +58,7 @@ bool(true) bool(true) mb_ord(): Argument #1 ($str) must not be empty mb_ord(): Argument #2 ($encoding) must be a valid encoding, "typo" given -mb_ord() does not support the "pass" encoding +mb_ord(): Argument #2 ($encoding) must be a valid encoding, "pass" given mb_ord() does not support the "JIS" encoding mb_ord() does not support the "CP50222" encoding mb_ord() does not support the "UTF-7" encoding diff --git a/ext/mbstring/tests/mb_output_handler_pass.phpt b/ext/mbstring/tests/mb_output_handler_pass.phpt new file mode 100644 index 0000000000..833eb42301 --- /dev/null +++ b/ext/mbstring/tests/mb_output_handler_pass.phpt @@ -0,0 +1,27 @@ +--TEST-- +mb_output_handler() with output_encoding=pass +--SKIPIF-- + +--INI-- +output_handler=mb_output_handler +output_encoding=pass +--FILE-- + +--EXPECT-- +string(4) "pass" +string(1) "ÿ" +string(1) "?" +string(1) "ÿ" diff --git a/ext/mbstring/tests/mb_preferred_mime_name.phpt b/ext/mbstring/tests/mb_preferred_mime_name.phpt index 80369df71d..82ff80dfea 100644 --- a/ext/mbstring/tests/mb_preferred_mime_name.phpt +++ b/ext/mbstring/tests/mb_preferred_mime_name.phpt @@ -41,10 +41,8 @@ try { echo $e->getMessage() . \PHP_EOL; } -// No preferred name -var_dump(mb_preferred_mime_name('pass')); ?> ---EXPECTF-- +--EXPECT-- Shift_JIS Shift_JIS EUC-JP @@ -56,6 +54,3 @@ UCS-2 UCS-4 == INVALID PARAMETER == mb_preferred_mime_name(): Argument #1 ($encoding) must be a valid encoding, "BAD_NAME" given - -Warning: mb_preferred_mime_name(): No MIME preferred name corresponding to "pass" in %s on line %d -bool(false) diff --git a/ext/mbstring/tests/mb_send_mail01.phpt b/ext/mbstring/tests/mb_send_mail01.phpt index 349fab852c..283ff11d6b 100644 --- a/ext/mbstring/tests/mb_send_mail01.phpt +++ b/ext/mbstring/tests/mb_send_mail01.phpt @@ -21,7 +21,7 @@ mb_send_mail($to, mb_language(), "test"); /* neutral (UTF-8) */ if (mb_language("neutral")) { - mb_internal_encoding("none"); + mb_internal_encoding("UTF-8"); mb_send_mail($to, "test ".mb_language(), "test"); } ?>