From: Viktor Szakats Date: Tue, 18 Nov 2025 00:48:04 +0000 (+0100) Subject: curlx: replace `mbstowcs`/`wcstombs` with `_s` counterparts (Windows) X-Git-Tag: rc-8_18_0-1~191 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18b94293133c1e035b5ac5b4fde854d1f17418a3;p=thirdparty%2Fcurl.git curlx: replace `mbstowcs`/`wcstombs` with `_s` counterparts (Windows) They are used in Windows-specific `fopen()`, `freopen`, `open()` and `curlx_get_winapi_error()` calls, and in `fix_excessive_path()` in Unicode builds. Refs: https://learn.microsoft.com/cpp/c-runtime-library/reference/mbstowcs-mbstowcs-l https://learn.microsoft.com/cpp/c-runtime-library/reference/mbstowcs-s-mbstowcs-s-l https://learn.microsoft.com/cpp/c-runtime-library/reference/wcstombs-wcstombs-l https://learn.microsoft.com/cpp/c-runtime-library/reference/wcstombs-s-wcstombs-s-l Also ban these functions via checksrc. Co-authored-by: Jay Satiro Closes #19581 --- diff --git a/lib/curl_setup.h b/lib/curl_setup.h index d75de9416c..db438a8b0a 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -97,8 +97,7 @@ #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS /* for __sys_errlist, __sys_nerr, _open(), _wfopen(), _wopen(), fopen(), freopen(), - getenv(), gmtime(), mbstowcs(), sprintf(), - strcpy(), wcstombs(), + getenv(), gmtime(), sprintf(), strcpy(), in tests: localtime(), open(), sscanf() */ #endif #endif /* _MSC_VER */ diff --git a/lib/curlx/fopen.c b/lib/curlx/fopen.c index f330753162..dc1c2bb4e6 100644 --- a/lib/curlx/fopen.c +++ b/lib/curlx/fopen.c @@ -97,15 +97,16 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out) #ifndef _UNICODE /* convert multibyte input to unicode */ - needed = mbstowcs(NULL, in, 0); - if(needed == (size_t)-1 || needed >= max_path_len) + if(mbstowcs_s(&needed, NULL, 0, in, 0)) + goto cleanup; + if(!needed || needed >= max_path_len) goto cleanup; - ++needed; /* for NUL */ ibuf = (malloc)(needed * sizeof(wchar_t)); if(!ibuf) goto cleanup; - count = mbstowcs(ibuf, in, needed); - if(count == (size_t)-1 || count >= needed) + if(mbstowcs_s(&count, ibuf, needed, in, needed - 1)) + goto cleanup; + if(count != needed) goto cleanup; in_w = ibuf; #else @@ -193,15 +194,16 @@ static bool fix_excessive_path(const TCHAR *in, TCHAR **out) #ifndef _UNICODE /* convert unicode full path to multibyte output */ - needed = wcstombs(NULL, fbuf, 0); - if(needed == (size_t)-1 || needed >= max_path_len) + if(wcstombs_s(&needed, NULL, 0, fbuf, 0)) + goto cleanup; + if(!needed || needed >= max_path_len) goto cleanup; - ++needed; /* for NUL */ obuf = (malloc)(needed); if(!obuf) goto cleanup; - count = wcstombs(obuf, fbuf, needed); - if(count == (size_t)-1 || count >= needed) + if(wcstombs_s(&count, obuf, needed, fbuf, needed - 1)) + goto cleanup; + if(count != needed) goto cleanup; *out = obuf; obuf = NULL; diff --git a/lib/curlx/winapi.c b/lib/curlx/winapi.c index 2dc277c1c1..7b3d6b6036 100644 --- a/lib/curlx/winapi.c +++ b/lib/curlx/winapi.c @@ -52,6 +52,7 @@ const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen) { char *p; wchar_t wbuf[256]; + DWORD wlen; if(!buflen) return NULL; @@ -62,23 +63,18 @@ const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen) /* We return the local codepage version of the error string because if it is output to the user's terminal it will likely be with functions which expect the local codepage (eg fprintf, failf, infof). */ - if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, - LANG_NEUTRAL, wbuf, CURL_ARRAYSIZE(wbuf), NULL)) { - size_t written = wcstombs(buf, wbuf, buflen - 1); - if(written != (size_t)-1) - buf[written] = '\0'; - else - *buf = '\0'; - } - - /* Truncate multiple lines */ - p = strchr(buf, '\n'); - if(p) { - if(p > buf && *(p-1) == '\r') - *(p-1) = '\0'; - else - *p = '\0'; + wlen = FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, wbuf, CURL_ARRAYSIZE(wbuf), NULL); + if(wlen && !wcstombs_s(NULL, buf, buflen, wbuf, wlen)) { + /* Truncate multiple lines */ + p = strchr(buf, '\n'); + if(p) { + if(p > buf && *(p-1) == '\r') + *(p-1) = '\0'; + else + *p = '\0'; + } } return *buf ? buf : NULL; diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 88db59f116..a2f458b6c1 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -86,6 +86,8 @@ my %banfunc = ( "wcsdup" => 1, "wcscpy" => 1, "wcsncpy" => 1, + "mbstowcs" => 1, + "wcstombs" => 1, "LoadLibrary" => 1, "LoadLibraryA" => 1, "LoadLibraryW" => 1,