← Commit list

64f28b8f88

Viktor Szakats
Viktor Szakats
2026-03-02
SUCCESS Duration: 303s

Subject

curlx: add local `snprintf()` helper that always nul-terminates (Windows)

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/Makefile.inc+1 -0
@@ -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 \
lib/curl_setup.h+1 -1
@@ -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 */
lib/curlx/snprintf.c+49 -0
@@ -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 */
lib/curlx/snprintf.h+11 -2
@@ -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 */
lib/mprintf.c+7 -12
@@ -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) {
tests/server/Makefile.inc+1 -0
@@ -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 \
tests/server/first.h+3 -3
@@ -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
tests/server/tftpd.c+3 -2
@@ -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);