]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curlx: replace `mbstowcs`/`wcstombs` with `_s` counterparts (Windows)
authorViktor Szakats <commit@vsz.me>
Tue, 18 Nov 2025 00:48:04 +0000 (01:48 +0100)
committerViktor Szakats <commit@vsz.me>
Fri, 21 Nov 2025 15:45:42 +0000 (16:45 +0100)
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

lib/curl_setup.h
lib/curlx/fopen.c
lib/curlx/winapi.c
scripts/checksrc.pl

index d75de9416cbf0ac3df476b2f43e52b1fceeaf525..db438a8b0a473186670e76871e7362eb8195f957 100644 (file)
@@ -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 */
index f3307531625072bc7b64be04b207dd55afc9c600..dc1c2bb4e67deb6b24b951fabe697741571c0355 100644 (file)
@@ -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;
index 2dc277c1c1fa2b76589654a7fb1233acc7b98c98..7b3d6b60369caea7b5068cc2b51b8ac2b74d56ee 100644 (file)
@@ -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;
index 88db59f116d12be4248597a70c139bc2f117553a..a2f458b6c1ac4890e6284b8ec9ed922888e87a44 100755 (executable)
@@ -86,6 +86,8 @@ my %banfunc = (
     "wcsdup" => 1,
     "wcscpy" => 1,
     "wcsncpy" => 1,
+    "mbstowcs" => 1,
+    "wcstombs" => 1,
     "LoadLibrary" => 1,
     "LoadLibraryA" => 1,
     "LoadLibraryW" => 1,