mirror of
https://github.com/curl/curl.git
synced 2026-04-14 18:11:40 +03:00
curlx: add local snprintf() helper that always nul-terminates (Windows)
Make the helper use `vsnprintf()` internally on all supported Windows toolchains (dropping `_snprintf()` and `snprintf()`), ensure to nul-terminate. Omit the return value to avoid complexity. Use the helper from `mprintf.c` / `out_double()`, from tests/server code and the tests/server-specific build of `curlx_inet_ntop()`, `curlx_strerror()` functions. In the single call (in tests) where the returned length was used previously, determine it with `strlen()`. Refs: https://github.com/libssh2/libssh2/blob/libssh2-1.11.1/src/misc.c#L57-L79 https://learn.microsoft.com/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l https://learn.microsoft.com/cpp/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l Assisted-by: Jay Satiro Follow-up tofa8bd1cc09#20761 Follow-up to8ab468c8aa#15997 Closes #20765
This commit is contained in:
parent
b83ade783d
commit
64f28b8f88
8 changed files with 76 additions and 20 deletions
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
49
lib/curlx/snprintf.c
Normal file
49
lib/curlx/snprintf.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue