From 1eca08a5417740320501448b64e8584de349126c Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Fri, 21 Nov 2025 15:55:33 +0100 Subject: [PATCH] curlx/strerr: use `strerror_s()` on Windows To replace deprecated, unsafe `sys_nerr`, `sys_errlist` global variables with the function suggested by the CRT warning silenced via `_CRT_SECURE_NO_WARNINGS`: ``` lib/curlx/strerr.c(291): warning C4996: '__sys_nerr': This function or variable may be unsafe. Consider using strerror instead. lib/curlx/strerr.c(292): warning C4996: '__sys_errlist': This function or variable may be unsafe. Consider using strerror instead. ``` (where `strerror` in turn suggests `strerror_s`...) Upside: returns an error and has a Unicode variant. Downaside: happy to return success when passing unrecognized error codes. Work it around by looking for the string "Unknown error" returned in such cases and falling back to other methods to retrieve a description. Refs: https://learn.microsoft.com/cpp/c-runtime-library/errno-doserrno-sys-errlist-and-sys-nerr https://learn.microsoft.com/cpp/c-runtime-library/reference/strerror-s-strerror-s-wcserror-s-wcserror-s Closes #19646 --- lib/curl_setup.h | 6 +++--- lib/curlx/strerr.c | 13 ++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/curl_setup.h b/lib/curl_setup.h index db438a8b0a..886a881493 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -95,9 +95,9 @@ unlink(), etc. */ #endif #ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS /* for __sys_errlist, __sys_nerr, _open(), - _wfopen(), _wopen(), fopen(), freopen(), - getenv(), gmtime(), sprintf(), strcpy(), +#define _CRT_SECURE_NO_WARNINGS /* for _open(), _wfopen(), _wopen(), fopen(), + freopen(), getenv(), gmtime(), sprintf(), + strcpy(), in tests: localtime(), open(), sscanf() */ #endif #endif /* _MSC_VER */ diff --git a/lib/curlx/strerr.c b/lib/curlx/strerr.c index 047588ed18..376f68b0b2 100644 --- a/lib/curlx/strerr.c +++ b/lib/curlx/strerr.c @@ -287,17 +287,12 @@ const char *curlx_strerror(int err, char *buf, size_t buflen) *buf = '\0'; #ifdef _WIN32 - /* 'sys_nerr' is the maximum errno number, it is not widely portable */ - if(err >= 0 && err < sys_nerr) - SNPRINTF(buf, buflen, "%s", sys_errlist[err]); - else { - if( + if((!strerror_s(buf, buflen, err) || !strcmp(buf, "Unknown error")) && #ifdef USE_WINSOCK - !get_winsock_error(err, buf, buflen) && + !get_winsock_error(err, buf, buflen) && #endif - !curlx_get_winapi_error((DWORD)err, buf, buflen)) - SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err); - } + !curlx_get_winapi_error((DWORD)err, buf, buflen)) + SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err); #else /* !_WIN32 */ #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) -- 2.47.3