diff --git a/src/inet.c b/src/inet.c index c948b2e7..da63a688 100644 --- a/src/inet.c +++ b/src/inet.c @@ -55,11 +55,7 @@ static int inet_ntop4(const unsigned char *src, char *dst, size_t size) { char tmp[UV__INET_ADDRSTRLEN]; int l; -#ifndef _WIN32 l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#else - l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); -#endif if (l <= 0 || (size_t) l >= size) { return UV_ENOSPC; } diff --git a/src/uv-common.c b/src/uv-common.c index 675a776b..8ce3d1f4 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -141,11 +141,7 @@ static const char* uv__unknown_err_code(int err) { char buf[32]; char* copy; -#ifndef _WIN32 snprintf(buf, sizeof(buf), "Unknown system error %d", err); -#else - _snprintf(buf, sizeof(buf), "Unknown system error %d", err); -#endif copy = uv__strdup(buf); return copy != NULL ? copy : "Unknown system error"; diff --git a/src/uv-common.h b/src/uv-common.h index b348ec76..27902fdf 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -41,6 +41,10 @@ #include "tree.h" #include "queue.h" +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); +#endif + #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define container_of(ptr, type, member) \ diff --git a/src/win/pipe.c b/src/win/pipe.c index 8312b1ce..796d06dc 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -85,7 +85,7 @@ static void eof_timer_close_cb(uv_handle_t* handle); static void uv_unique_pipe_name(char* ptr, char* name, size_t size) { - _snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId()); + snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId()); } diff --git a/src/win/snprintf.c b/src/win/snprintf.c new file mode 100644 index 00000000..b589417a --- /dev/null +++ b/src/win/snprintf.c @@ -0,0 +1,41 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if defined(_MSC_VER) && _MSC_VER < 1900 + +#include +#include + +/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer + * on overflow... + */ +int snprintf(char* buf, size_t len, const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + + int n = _vscprintf(fmt, ap); + vsnprintf_s(buf, len, _TRUNCATE, fmt, ap); + + va_end(ap); + return n; +} + +#endif diff --git a/test/runner-win.h b/test/runner-win.h index c94b89bd..8cc4c16e 100644 --- a/test/runner-win.h +++ b/test/runner-win.h @@ -19,9 +19,6 @@ * IN THE SOFTWARE. */ -/* Don't complain about _snprintf being insecure. */ -#define _CRT_SECURE_NO_WARNINGS - /* Don't complain about write(), fileno() etc. being deprecated. */ #pragma warning(disable : 4996) @@ -30,10 +27,9 @@ #include #include - -/* Windows has no snprintf, only _snprintf. */ -#define snprintf _snprintf - +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); +#endif typedef struct { HANDLE process; diff --git a/test/task.h b/test/task.h index e7367638..8999c20a 100644 --- a/test/task.h +++ b/test/task.h @@ -174,40 +174,8 @@ enum test_status { #endif - -#if defined _WIN32 && ! defined __GNUC__ - -#include - -/* Define inline for MSVC<2015 */ -# if defined(_MSC_VER) && _MSC_VER < 1900 -# define inline __inline -# endif - -# if defined(_MSC_VER) && _MSC_VER < 1900 -/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer - * on overflow... - */ -inline int snprintf(char* buf, size_t len, const char* fmt, ...) { - va_list ap; - int n; - - va_start(ap, fmt); - n = _vsprintf_p(buf, len, fmt, ap); - va_end(ap); - - /* It's a sad fact of life that no one ever checks the return value of - * snprintf(). Zero-terminating the buffer hopefully reduces the risk - * of gaping security holes. - */ - if (n < 0) - if (len > 0) - buf[0] = '\0'; - - return n; -} -# endif - +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); #endif #if defined(__clang__) || \ diff --git a/test/test-spawn.c b/test/test-spawn.c index e71f0f7d..eba54ae7 100644 --- a/test/test-spawn.c +++ b/test/test-spawn.c @@ -960,11 +960,11 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) { options.stdio_count = 2; /* Create a pipe that'll cause a collision. */ - _snprintf(name, - sizeof(name), - "\\\\.\\pipe\\uv\\%p-%d", - &out, - GetCurrentProcessId()); + snprintf(name, + sizeof(name), + "\\\\.\\pipe\\uv\\%p-%d", + &out, + GetCurrentProcessId()); pipe_handle = CreateNamedPipeA(name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, diff --git a/uv.gyp b/uv.gyp index 8049faa7..36cc8abe 100644 --- a/uv.gyp +++ b/uv.gyp @@ -104,6 +104,13 @@ 'src/win/winsock.c', 'src/win/winsock.h', ], + 'conditions': [ + ['MSVS_VERSION < "2015"', { + 'sources': [ + 'src/win/snprintf.c' + ] + }] + ], 'link_settings': { 'libraries': [ '-ladvapi32',