curlx/fopen: replace open CRT functions their with _s counterparts (Windows)

- `_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
This commit is contained in:
Viktor Szakats 2025-11-18 01:32:43 +01:00
parent ee97c2a96a
commit 1e7d0bafc6
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
5 changed files with 31 additions and 16 deletions

View file

@ -95,10 +95,9 @@
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 */

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