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 6694a42aa0 #19798

Closes #22326
This commit is contained in:
Viktor Szakats 2026-07-14 19:06:37 +02:00
parent cb81c5f4e2
commit d52c7e78a3
No known key found for this signature in database
4 changed files with 9 additions and 9 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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))