]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curlx/fopen: replace open CRT functions their with `_s` counterparts (Windows)
authorViktor Szakats <commit@vsz.me>
Tue, 18 Nov 2025 00:32:43 +0000 (01:32 +0100)
committerViktor Szakats <commit@vsz.me>
Tue, 25 Nov 2025 02:44:22 +0000 (03:44 +0100)
- `_wopen`        -> `_wsopen_s`
- `_open`, `open` -> `_sopen_s`
- `_wfopen`       -> `_wfopen_s`
- `fopen`         -> `fopen_s`
- `_wfreopen`     -> `_wfreopen_s`
- `freopen`       -> `freopen_s`

For better error handling and for using the CRT functions recommended
via warnings suppressed by `_CRT_SECURE_NO_WARNINGS`.

Also:
- add missing `freopen_s()` prototype when building with mingw-w64 <5.
  https://sourceforge.net/p/mingw-w64/mingw-w64/ci/a5d824654cdc57f6eac1bb581b078986f3eb6856/
- tests/server: replace `open()` in the signal handler with `_sopen_s()`
  on Windows.
- tests/server: reduce scope of a checksrc exception to a single line.
- checksrc: ban replaced functions.

Refs:
https://learn.microsoft.com/cpp/c-runtime-library/reference/open-wopen
https://learn.microsoft.com/cpp/c-runtime-library/reference/sopen-s-wsopen-s
https://learn.microsoft.com/cpp/c-runtime-library/reference/freopen-wfreopen
https://learn.microsoft.com/cpp/c-runtime-library/reference/fopen-wfopen
https://learn.microsoft.com/cpp/c-runtime-library/reference/fopen-s-wfopen-s
https://learn.microsoft.com/cpp/c-runtime-library/reference/freopen-s-wfreopen-s

Closes #19643

lib/curl_setup.h
lib/curlx/fopen.c
scripts/checksrc.pl
tests/server/.checksrc
tests/server/util.c

index 886a8814936ae9af0ca590ab3783852534549b4e..0e5ebb60c9ef31a3ad64c049b5a4b08a7e07fe37 100644 (file)
                                       unlink(), etc. */
 #endif
 #ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS  /* for _open(), _wfopen(), _wopen(), fopen(),
-                                    freopen(), getenv(), gmtime(), sprintf(),
+#define _CRT_SECURE_NO_WARNINGS  /* for getenv(), gmtime(), sprintf(),
                                     strcpy(),
-                                    in tests: localtime(), open(), sscanf() */
+                                    in tests: localtime(), sscanf() */
 #endif
 #endif /* _MSC_VER */
 
index dc1c2bb4e67deb6b24b951fabe697741571c0355..0dc9699206cda4d4bd98a6d5651b4e79ab6774f0 100644 (file)
@@ -51,6 +51,8 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence)
 
 #include "multibyte.h"
 
+#include <share.h>  /* for _SH_DENYNO */
+
 /* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */
 #if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \
   (_WIN32_WINNT < _WIN32_WINNT_WIN10)
@@ -244,7 +246,7 @@ int curlx_win32_open(const char *filename, int oflag, ...)
       target = fixed;
     else
       target = filename_w;
-    result = _wopen(target, oflag, pmode);
+    errno = _wsopen_s(&result, target, oflag, _SH_DENYNO, pmode);
     curlx_unicodefree(filename_w);
   }
   else
@@ -255,7 +257,7 @@ int curlx_win32_open(const char *filename, int oflag, ...)
     target = fixed;
   else
     target = filename;
-  result = _open(target, oflag, pmode);
+  errno = _sopen_s(&result, target, oflag, _SH_DENYNO, pmode);
 #endif
 
   (free)(fixed);
@@ -276,7 +278,7 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
       target = fixed;
     else
       target = filename_w;
-    result = _wfopen(target, mode_w);
+    errno = _wfopen_s(&result, target, mode_w);
   }
   else
     /* !checksrc! disable ERRNOVAR 1 */
@@ -288,14 +290,18 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode)
     target = fixed;
   else
     target = filename;
-  /* !checksrc! disable BANNEDFUNC 1 */
-  result = fopen(target, mode);
+  errno = fopen_s(&result, target, mode);
 #endif
 
   (free)(fixed);
   return result;
 }
 
+#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 5)
+_CRTIMP errno_t __cdecl freopen_s(FILE **file, const char *filename,
+                                  const char *mode, FILE *stream);
+#endif
+
 FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp)
 {
   FILE *result = NULL;
@@ -310,7 +316,7 @@ FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp)
       target = fixed;
     else
       target = filename_w;
-    result = _wfreopen(target, mode_w, fp);
+    errno = _wfreopen_s(&result, target, mode_w, fp);
   }
   else
     /* !checksrc! disable ERRNOVAR 1 */
@@ -322,8 +328,7 @@ FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp)
     target = fixed;
   else
     target = filename;
-  /* !checksrc! disable BANNEDFUNC 1 */
-  result = freopen(target, mode, fp);
+  errno = freopen_s(&result, target, mode, fp);
 #endif
 
   (free)(fixed);
index a2f458b6c1ac4890e6284b8ec9ed922888e87a44..d38ffecdb9b1a2e85dcd10639c207844a6c8fb50 100755 (executable)
@@ -113,6 +113,10 @@ my %banfunc = (
     "fopen" => 1,
     "freopen" => 1,
     "open" => 1,
+    "_open" => 1,
+    "_wfopen" => 1,
+    "_wfreopen" => 1,
+    "_wopen" => 1,
     "stat" => 1,
     );
 
index 0386c677e6c3255b9c31b8383437b63ca900714a..163a217ee4be12a28bed5b94182939f62c2df2c3 100644 (file)
@@ -6,7 +6,6 @@ allowfunc accept
 allowfunc fprintf
 allowfunc freeaddrinfo
 allowfunc getaddrinfo
-allowfunc open
 allowfunc printf
 allowfunc recv
 allowfunc send
index 8d8bf12c99dd529ceae41a9dfe24c7c006111376..ae21ff8b1af8eef1dcc81f44574e29f2bac64358 100644 (file)
 #include <fcntl.h>
 #endif
 
+#ifdef _WIN32
+#include <share.h>
+#endif
+
 /* This function returns a pointer to STATIC memory. It converts the given
  * binary lump to a hex formatted string usable for output in logs or
  * whatever.
@@ -359,13 +363,17 @@ static void exit_signal_handler(int signum)
     (void)!write(STDERR_FILENO, msg, sizeof(msg) - 1);
   }
   else {
+    int fd = -1;
 #ifdef _WIN32
-#define OPENMODE S_IREAD | S_IWRITE
+    if(!_sopen_s(&fd, serverlogfile, O_WRONLY | O_CREAT | O_APPEND,
+                 _SH_DENYNO, S_IREAD | S_IWRITE) &&
+       fd != -1) {
 #else
-#define OPENMODE S_IRUSR | S_IWUSR
-#endif
-    int fd = open(serverlogfile, O_WRONLY | O_CREAT | O_APPEND, OPENMODE);
+    /* !checksrc! disable BANNEDFUNC 1 */
+    fd = open(serverlogfile,
+              O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
     if(fd != -1) {
+#endif
       static const char msg[] = "exit_signal_handler: called\n";
       (void)!write(fd, msg, sizeof(msg) - 1);
       close(fd);