curlx: add local `snprintf()` helper that always nul-terminates (Windows)
No binary (build failed)
—
(log yok)
| @@ -32,6 +32,7 @@ LIB_CURLX_CFILES = \ | |
| curlx/inet_pton.c \ | |
| curlx/multibyte.c \ | |
| curlx/nonblock.c \ | |
| + | curlx/snprintf.c \ |
| curlx/strcopy.c \ | |
| curlx/strdup.c \ | |
| curlx/strerr.c \ | |
| @@ -90,7 +90,7 @@ | |
| /* Disable Visual Studio warnings: 4127 "conditional expression is constant" */ | |
| #pragma warning(disable:4127) | |
| #ifndef _CRT_SECURE_NO_WARNINGS | |
| - | #define _CRT_SECURE_NO_WARNINGS /* for _snprintf(), getenv(), sscanf() */ |
| + | #define _CRT_SECURE_NO_WARNINGS /* for getenv(), sscanf() */ |
| #endif | |
| #endif /* _MSC_VER */ | |
| @@ -0,0 +1,49 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | * |
| + | * This software is licensed as described in the file COPYING, which |
| + | * you should have received as part of this distribution. The terms |
| + | * are also available at https://curl.se/docs/copyright.html. |
| + | * |
| + | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
| + | * copies of the Software, and permit persons to whom the Software is |
| + | * furnished to do so, under the terms of the COPYING file. |
| + | * |
| + | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| + | * KIND, either express or implied. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "curlx/snprintf.h" |
| + | |
| + | #ifdef _WIN32 |
| + | #include <stdarg.h> |
| + | |
| + | /* Simplified wrapper for the Windows platform to use the correct symbol and |
| + | ensuring null-termination. Omit returning a length to keep it simple. */ |
| + | void curlx_win32_snprintf(char *buf, size_t maxlen, const char *fmt, ...) |
| + | { |
| + | va_list ap; |
| + | if(!maxlen) |
| + | return; |
| + | va_start(ap, fmt); |
| + | #if defined(__GNUC__) || defined(__clang__) |
| + | #pragma GCC diagnostic push |
| + | #pragma GCC diagnostic ignored "-Wformat-nonliteral" |
| + | #endif |
| + | /* !checksrc! disable BANNEDFUNC 1 */ |
| + | (void)vsnprintf(buf, maxlen, fmt, ap); |
| + | #if defined(__GNUC__) || defined(__clang__) |
| + | #pragma GCC diagnostic pop |
| + | #endif |
| + | buf[maxlen - 1] = 0; |
| + | va_end(ap); |
| + | } |
| + | #endif /* _WIN32 */ |
| @@ -1,3 +1,5 @@ | |
| + | #ifndef HEADER_CURLX_SNPRINTF_H |
| + | #define HEADER_CURLX_SNPRINTF_H |
| /*************************************************************************** | |
| * _ _ ____ _ | |
| * Project ___| | | | _ \| | | |
| @@ -21,12 +23,18 @@ | |
| * SPDX-License-Identifier: curl | |
| * | |
| ***************************************************************************/ | |
| + | #include "curl_setup.h" |
| /* Raw snprintf() for curlx */ | |
| + | #ifdef _WIN32 |
| + | void curlx_win32_snprintf(char *buf, size_t maxlen, const char *fmt, ...) |
| + | CURL_PRINTF(3, 4); |
| + | #endif |
| + | |
| #ifdef WITHOUT_LIBCURL /* when built for the test servers */ | |
| - | #if defined(_MSC_VER) && (_MSC_VER < 1900) /* adjust for old MSVC */ |
| - | #define SNPRINTF _snprintf |
| + | #ifdef _WIN32 |
| + | #define SNPRINTF curlx_win32_snprintf |
| #else | |
| #define SNPRINTF snprintf | |
| #endif | |
| @@ -34,3 +42,4 @@ | |
| #include <curl/mprintf.h> | |
| #define SNPRINTF curl_msnprintf | |
| #endif /* WITHOUT_LIBCURL */ | |
| + | #endif /* HEADER_CURLX_SNPRINTF_H */ |
| @@ -26,6 +26,7 @@ | |
| #include "curlx/dynbuf.h" | |
| #include "curl_printf.h" | |
| #include "curlx/strparse.h" | |
| + | #include "curlx/snprintf.h" /* for curlx_win32_snprintf() */ |
| #define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should | |
| fit negative DBL_MAX (317 letters) */ | |
| @@ -671,29 +672,23 @@ static bool out_double(void *userp, | |
| /* NOTE NOTE NOTE!! Not all sprintf implementations return number of | |
| output characters */ | |
| - | #ifdef HAVE_SNPRINTF |
| #if defined(__GNUC__) || defined(__clang__) | |
| #pragma GCC diagnostic push | |
| #pragma GCC diagnostic ignored "-Wformat-nonliteral" | |
| #endif | |
| + | #ifdef _WIN32 |
| + | curlx_win32_snprintf(work, BUFFSIZE, formatbuf, dnum); |
| + | #elif defined(HAVE_SNPRINTF) |
| /* !checksrc! disable BANNEDFUNC 1 */ | |
| /* !checksrc! disable LONGLINE */ | |
| /* NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) */ | |
| snprintf(work, BUFFSIZE, formatbuf, dnum); | |
| - | #if defined(__GNUC__) || defined(__clang__) |
| - | #pragma GCC diagnostic pop |
| - | #endif |
| - | #ifdef _WIN32 |
| - | /* Old versions of the Windows CRT do not terminate the snprintf output |
| - | buffer if it reaches the max size so we do that here. */ |
| - | work[BUFFSIZE - 1] = 0; |
| - | #endif |
| - | #elif defined(_MSC_VER) && (_MSC_VER < 1900) |
| - | _snprintf(work, BUFFSIZE, formatbuf, dnum); |
| - | work[BUFFSIZE - 1] = 0; |
| #else | |
| /* float and double outputs do not work without snprintf support */ | |
| work[0] = 0; | |
| + | #endif |
| + | #if defined(__GNUC__) || defined(__clang__) |
| + | #pragma GCC diagnostic pop |
| #endif | |
| DEBUGASSERT(strlen(work) < BUFFSIZE); | |
| while(*work) { | |
| @@ -40,6 +40,7 @@ CURLX_C = \ | |
| ../../lib/curlx/inet_pton.c \ | |
| ../../lib/curlx/multibyte.c \ | |
| ../../lib/curlx/nonblock.c \ | |
| + | ../../lib/curlx/snprintf.c \ |
| ../../lib/curlx/strcopy.c \ | |
| ../../lib/curlx/strerr.c \ | |
| ../../lib/curlx/strparse.c \ | |
| @@ -64,9 +64,9 @@ extern const struct entry_s s_entries[]; | |
| #include <curlx/curlx.h> | |
| - | /* adjust for old MSVC */ |
| - | #if defined(_MSC_VER) && (_MSC_VER < 1900) |
| - | # define snprintf _snprintf |
| + | #ifdef _WIN32 |
| + | #include <curlx/snprintf.h> |
| + | #define snprintf curlx_win32_snprintf |
| #endif | |
| #ifdef _WIN32 | |
| @@ -606,8 +606,9 @@ static int validate_access(struct testcase *test, | |
| if(!strncmp("verifiedserver", filename, 14)) { | |
| char weare[128]; | |
| - | size_t count = snprintf(weare, sizeof(weare), "WE ROOLZ: %ld\r\n", |
| - | (long)our_getpid()); |
| + | size_t count; |
| + | snprintf(weare, sizeof(weare), "WE ROOLZ: %ld\r\n", (long)our_getpid()); |
| + | count = strlen(weare); |
| logmsg("Are-we-friendly question received"); | |
| test->buffer = curlx_strdup(weare); | |