diff --git a/UPGRADING b/UPGRADING index fea6cc199e2ad..890e3fc2256b4 100644 --- a/UPGRADING +++ b/UPGRADING @@ -55,6 +55,8 @@ PHP 8.4 UPGRADE NOTES . mb_encode_numericentity() and mb_decode_numericentity() now check that the $map is only composed of integers, if not a ValueError is thrown. . mb_http_input() now always throws a ValueError if the $type is invalid. + . mb_http_output() now checks that the $encoding parameter does not + contain any null bytes. If it does, a ValueError is now thrown. . On invalid strings (those with encoding errors), mb_substr() now interprets character indices in the same manner as most other mbstring functions. This means that character indices returned by mb_strpos() can be passed to mb_substr(). diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 4e947de21aaed..0a86fa42649a9 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -269,12 +269,12 @@ 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) { +static const mbfl_encoding *php_mb_get_encoding_or_pass(const char *encoding_name, size_t encoding_name_len) { + if (strncmp(encoding_name, "pass", encoding_name_len) == 0) { return &mbfl_encoding_pass; } - return mbfl_name2encoding(encoding_name); + return mbfl_name2encoding_ex(encoding_name, encoding_name_len); } static size_t count_commas(const char *p, const char *end) { @@ -760,8 +760,8 @@ static PHP_INI_MH(OnUpdate_mbstring_http_input) } /* }}} */ -static zend_result _php_mb_ini_mbstring_http_output_set(const char *new_value) { - const mbfl_encoding *encoding = php_mb_get_encoding_or_pass(new_value); +static zend_result _php_mb_ini_mbstring_http_output_set(const char *new_value, size_t length) { + const mbfl_encoding *encoding = php_mb_get_encoding_or_pass(new_value, length); if (!encoding) { return FAILURE; } @@ -779,13 +779,14 @@ static PHP_INI_MH(OnUpdate_mbstring_http_output) } if (new_value == NULL || ZSTR_LEN(new_value) == 0) { + const char *encoding = php_get_output_encoding(); MBSTRG(http_output_set) = 0; - _php_mb_ini_mbstring_http_output_set(php_get_output_encoding()); + _php_mb_ini_mbstring_http_output_set(encoding, strlen(encoding)); return SUCCESS; } MBSTRG(http_output_set) = 1; - return _php_mb_ini_mbstring_http_output_set(ZSTR_VAL(new_value)); + return _php_mb_ini_mbstring_http_output_set(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); } /* }}} */ @@ -966,7 +967,7 @@ static void mbstring_internal_encoding_changed_hook(void) { if (!MBSTRG(http_output_set)) { const char *encoding = php_get_output_encoding(); - _php_mb_ini_mbstring_http_output_set(encoding); + _php_mb_ini_mbstring_http_output_set(encoding, strlen(encoding)); } if (!MBSTRG(http_input_set)) { @@ -1340,14 +1341,14 @@ PHP_FUNCTION(mb_http_output) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(name, name_len) + Z_PARAM_PATH_OR_NULL(name, name_len) /* For null byte check */ ZEND_PARSE_PARAMETERS_END(); if (name == NULL) { ZEND_ASSERT(MBSTRG(current_http_output_encoding)); RETURN_STRING(MBSTRG(current_http_output_encoding)->name); } else { - const mbfl_encoding *encoding = php_mb_get_encoding_or_pass(name); + const mbfl_encoding *encoding = php_mb_get_encoding_or_pass(name, name_len); if (!encoding) { zend_argument_value_error(1, "must be a valid encoding, \"%s\" given", name); RETURN_THROWS();