Fix snprintf emulation for Windows
* Move it into separate win32_snprintf.h file to de-duplicate its implementation from all miniupnp source files. * Do not use this emulation with mingw32 SDK when __NO_ISOCEXT is not defined as in this case mingw32 provides working snprintf function. * Fix detection for mingw-w64 variants, when __NO_ISOCEXT is defined or when older version without UCRT is used. * Add check if _scprintf function is available. In case it is not available just returns length of filled buffer to prevent buffer overflow.
This commit is contained in:
parent
a3522723ae
commit
8cd542a809
|
@ -19,11 +19,7 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#define herror
|
#define herror
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#else /* #ifdef _WIN32 */
|
#else /* #ifdef _WIN32 */
|
||||||
|
|
|
@ -13,11 +13,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
|
@ -20,11 +20,7 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#if !defined(_MSC_VER)
|
#if !defined(_MSC_VER)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else /* !defined(_MSC_VER) */
|
#else /* !defined(_MSC_VER) */
|
||||||
|
|
|
@ -15,11 +15,7 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#define strdup _strdup
|
#define strdup _strdup
|
||||||
#ifndef strncasecmp
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
|
|
@ -15,11 +15,7 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define MAXHOSTNAMELEN 64
|
#define MAXHOSTNAMELEN 64
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
#ifndef strncasecmp
|
#ifndef strncasecmp
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
|
|
@ -11,11 +11,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
/* snprintf is supported by Visual Studio 2015, mingw-w64 8.0.0, mingw-w64 with ucrt, mingw-w64 or mingw32 with ansi stdio */
|
#include "win32_snprintf.h"
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR < 8 && !defined(_UCRT) && !defined(__USE_MINGW_ANSI_STDIO)) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__USE_MINGW_ANSI_STDIO))
|
|
||||||
/* _snprintf does not fill nul byte at the end of buffer and returns -1 on overflow */
|
|
||||||
#define snprintf(buf, size, fmt, ...) ((_snprintf((buf), (size), (fmt), __VA_ARGS__), (((char *)buf)[(size_t)(size)-1] = 0), _scprintf((fmt), __VA_ARGS__)))
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
/* for IPPROTO_TCP / IPPROTO_UDP */
|
/* for IPPROTO_TCP / IPPROTO_UDP */
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||||
|
* MiniUPnP project
|
||||||
|
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||||
|
* (c) 2020 Pali Rohár
|
||||||
|
* This software is subject to the conditions detailed
|
||||||
|
* in the LICENCE file provided within the distribution */
|
||||||
|
|
||||||
|
#ifndef WIN32_SNPRINTF_H
|
||||||
|
#define WIN32_SNPRINTF_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* snprintf is supported by:
|
||||||
|
* - Visual Studio 2015 or new
|
||||||
|
* - mingw32 with iso c ext
|
||||||
|
* - mingw-w64 with ansi stdio
|
||||||
|
* - mingw-w64 6.0.0 or new with ucrt
|
||||||
|
* - mingw-w64 8.0.0 or new with iso c ext
|
||||||
|
*/
|
||||||
|
#if ( \
|
||||||
|
(defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \
|
||||||
|
(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \
|
||||||
|
(defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \
|
||||||
|
(defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \
|
||||||
|
(__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \
|
||||||
|
(__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \
|
||||||
|
0) || \
|
||||||
|
0)
|
||||||
|
|
||||||
|
/* _scprintf is supported by:
|
||||||
|
* - Visual Studio 2002 or new
|
||||||
|
* - msvcr70.dll or new
|
||||||
|
* - msvcrt.dll on Windows XP or new
|
||||||
|
*/
|
||||||
|
#if ( \
|
||||||
|
(defined(_MSC_VER) && _MSC_VER < 1300) /* Visual Studio older than 2002 */ || \
|
||||||
|
(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x700) /* msvcrt older than 7.0 */ || \
|
||||||
|
0)
|
||||||
|
#define CHECK_SCPRINTF 0
|
||||||
|
#define IF_SCPRINTF(expr) 0
|
||||||
|
#define ELSE_SCPRINTF(expr) expr
|
||||||
|
#else
|
||||||
|
#define CHECK_SCPRINTF 1
|
||||||
|
#define IF_SCPRINTF(expr) expr
|
||||||
|
#define ELSE_SCPRINTF(expr) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Emulation of snprintf for win32 */
|
||||||
|
#define snprintf(buf, size, fmt, ...) ( \
|
||||||
|
(((size) != 0 && (buf) != NULL) ? ( /* _snprintf does not work with NULL buffer */ \
|
||||||
|
_snprintf((buf), (size), (fmt), __VA_ARGS__), /* _snprintf returns -1 on overflow, so ignore its value */ \
|
||||||
|
(((char *)buf)[(size_t)(size)-1] = 0), /* _snprintf does not fill nul byte on overflow */ \
|
||||||
|
0) : 0), \
|
||||||
|
(CHECK_SCPRINTF ? IF_SCPRINTF( \
|
||||||
|
_scprintf((fmt), __VA_ARGS__) /* calculate return value for snprintf via _scprintf */ \
|
||||||
|
) : ELSE_SCPRINTF( \
|
||||||
|
((size) != 0 && (buf) != NULL) ? \
|
||||||
|
strlen((buf)) /* return just length of buffer */ \
|
||||||
|
: \
|
||||||
|
1 /* no buffer, impossible to calculate, return just non-zero number */ \
|
||||||
|
) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#endif /* WIN32_SNPRINTF_H */
|
Loading…
Reference in New Issue