From d52c7e78a3531f975591eb1bb1250185a9fd14c2 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 14 Jul 2026 19:06:37 +0200 Subject: [PATCH] idn: restore `MultiByteToWideChar()` `MB_ERR_INVALID_CHARS` flag Also: - curlx: pass this flag to the actual conversion calls, for consistency and robustness. (It's not stricly necessary because the initial call to determine size, with this flag passed, fails already on bad input.) - schannel: unfold `MultiByteToWideChar()` line (formatting). Ref: https://learn.microsoft.com/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar Follow-up to 6694a42aa0e820a6fe1e59d85ff8597b6d768d8d #19798 Closes #22326 --- lib/curlx/fopen.c | 2 +- lib/curlx/multibyte.c | 4 ++-- lib/idn.c | 6 ++++-- lib/vtls/schannel.c | 6 ++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/curlx/fopen.c b/lib/curlx/fopen.c index 37ca02671a..976eff9e2b 100644 --- a/lib/curlx/fopen.c +++ b/lib/curlx/fopen.c @@ -68,7 +68,7 @@ static wchar_t *fn_convert_UTF8_to_wchar(const char *str_utf8) if(str_w_len > 0) { str_w = CURLX_MALLOC(str_w_len * sizeof(wchar_t)); if(str_w) { - if(MultiByteToWideChar(CP_UTF8, 0, + if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str_utf8, -1, str_w, str_w_len) == 0) { CURLX_FREE(str_w); return NULL; diff --git a/lib/curlx/multibyte.c b/lib/curlx/multibyte.c index 715d2b8dc2..4ee39d962a 100644 --- a/lib/curlx/multibyte.c +++ b/lib/curlx/multibyte.c @@ -41,8 +41,8 @@ wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8) if(str_w_len > 0) { str_w = curlx_malloc(str_w_len * sizeof(wchar_t)); if(str_w) { - if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w, - str_w_len) == 0) { + if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + str_utf8, -1, str_w, str_w_len) == 0) { curlx_free(str_w); return NULL; } diff --git a/lib/idn.c b/lib/idn.c index b26f251d97..943a520eff 100644 --- a/lib/idn.c +++ b/lib/idn.c @@ -172,7 +172,8 @@ static CURLcode win32_idn_to_ascii(const char *in, char **out) /* Returned in_w_len includes the null-terminator, which then gets preserved across the calls that follow, ending up terminating the buffer returned to the caller. */ - in_w_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, in_w, IDN_MAX_LENGTH); + in_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + in, -1, in_w, IDN_MAX_LENGTH); if(in_w_len) { wchar_t punycode[IDN_MAX_LENGTH]; int chars = IdnToAscii(0, in_w, in_w_len, punycode, IDN_MAX_LENGTH); @@ -198,7 +199,8 @@ static CURLcode win32_ascii_to_idn(const char *in, char **out) /* Returned in_w_len includes the null-terminator, which then gets preserved across the calls that follow, ending up terminating the buffer returned to the caller. */ - in_w_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, in_w, IDN_MAX_LENGTH); + in_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + in, -1, in_w, IDN_MAX_LENGTH); if(in_w_len) { WCHAR idn[IDN_MAX_LENGTH]; /* stores a UTF-16 string */ int chars = IdnToUnicode(0, in_w, in_w_len, idn, IDN_MAX_LENGTH); diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index d322c755e8..2b8166de12 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -473,10 +473,8 @@ static CURLcode get_client_cert(struct Curl_cfilter *cf, if(pszPassword) { int str_w_len = 0; if(pwd_len > 0) - str_w_len = MultiByteToWideChar(CP_UTF8, - MB_ERR_INVALID_CHARS, - sslc->key_passwd, - (int)pwd_len, + str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + sslc->key_passwd, (int)pwd_len, pszPassword, (int)(pwd_len + 1)); if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))