From c93114ec9e45f4fb3843012056046eec15b875aa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 5 Nov 2021 12:08:48 -0400 Subject: Prefer use of __MINGW_PRINTF/SCANF_FORMAT if available. Mingw headers sometimes like to define alternative scanf/printf format attributes depending on whether they're using clang, UCRT, MINGW_ANSI_STDIO, or the microsoft version of printf/scanf. This change attempts to use the right one on the given platform. This is an attempt to fix part of #40355. --- changes/bug40355_part2 | 4 ++++ configure.ac | 4 +++- src/feature/api/tor_api.c | 4 +++- src/lib/cc/compat_compiler.h | 31 +++++++++++++++++++++++++------ src/lib/string/printf.c | 4 ++-- 5 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 changes/bug40355_part2 diff --git a/changes/bug40355_part2 b/changes/bug40355_part2 new file mode 100644 index 0000000000..000321d912 --- /dev/null +++ b/changes/bug40355_part2 @@ -0,0 +1,4 @@ + o Minor features (portability): + - Try to prevent a compiler warning about printf arguments that could + sometimes occur on MSYS2 depending on the configuration. + Closes ticket 40355. \ No newline at end of file diff --git a/configure.ac b/configure.ac index 366df64609..0d95b19796 100644 --- a/configure.ac +++ b/configure.ac @@ -689,6 +689,7 @@ AC_CHECK_FUNCS( readpassphrase \ rint \ sigaction \ + snprintf \ socketpair \ statvfs \ strncasecmp \ @@ -706,7 +707,8 @@ AC_CHECK_FUNCS( uname \ usleep \ vasprintf \ - _vscprintf + _vscprintf \ + vsnprintf ) # Apple messed up when they added some functions: they diff --git a/src/feature/api/tor_api.c b/src/feature/api/tor_api.c index 051be50b3a..88e91ebfd5 100644 --- a/src/feature/api/tor_api.c +++ b/src/feature/api/tor_api.c @@ -18,9 +18,9 @@ // Include this after the above headers, to insure that they don't // depend on anything else. #include "orconfig.h" +#include "lib/cc/compat_compiler.h" #include "lib/cc/torint.h" #include "feature/api/tor_api_internal.h" -#include "lib/cc/compat_compiler.h" #include #include @@ -39,7 +39,9 @@ #include "lib/net/socketpair.h" #define raw_socketpair tor_ersatz_socketpair #define raw_closesocket closesocket +#if !defined(HAVE_SNPRINTF) #define snprintf _snprintf +#endif #else /* !defined(_WIN32) */ #define raw_socketpair socketpair #define raw_closesocket close diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h index 50bfedffba..991b33d9e7 100644 --- a/src/lib/cc/compat_compiler.h +++ b/src/lib/cc/compat_compiler.h @@ -15,6 +15,15 @@ #include "orconfig.h" #include +#if defined(__MINGW32__) || defined(__MINGW64__) +#define MINGW_ANY +#endif + +#ifdef MINGW_ANY +/* We need this for __MINGW_PRINTF_FORMAT, alas. */ +#include +#endif + #if defined(__has_feature) # if __has_feature(address_sanitizer) /* Some of the fancy glibc strcmp() macros include references to memory that @@ -36,16 +45,30 @@ #error "It seems that you encode characters in something other than ASCII." #endif +/* Use the right magic attribute on mingw, which might be printf, gnu_printf, + * or ms_printf, depending on how we're set up to build. + */ +#ifdef __MINGW_PRINTF_FORMAT +#define PRINTF_FORMAT_ATTR __MINGW_PRINTF_FORMAT +#else +#define PRINTF_FORMAT_ATTR printf +#endif +#ifdef __MINGW_SCANF_FORMAT +#define SCANF_FORMAT_ATTR __MINGW_SCANF_FORMAT +#else +#define SCANF_FORMAT_ATTR scanf +#endif + /* GCC can check printf and scanf types on arbitrary functions. */ #ifdef __GNUC__ #define CHECK_PRINTF(formatIdx, firstArg) \ - __attribute__ ((format(printf, formatIdx, firstArg))) + __attribute__ ((format(PRINTF_FORMAT_ATTR, formatIdx, firstArg))) #else #define CHECK_PRINTF(formatIdx, firstArg) #endif /* defined(__GNUC__) */ #ifdef __GNUC__ #define CHECK_SCANF(formatIdx, firstArg) \ - __attribute__ ((format(scanf, formatIdx, firstArg))) + __attribute__ ((format(SCANF_FORMAT_ATTR, formatIdx, firstArg))) #else #define CHECK_SCANF(formatIdx, firstArg) #endif /* defined(__GNUC__) */ @@ -191,10 +214,6 @@ #define OP_EQ == #define OP_NE != -#if defined(__MINGW32__) || defined(__MINGW64__) -#define MINGW_ANY -#endif - /** Macro: yield a pointer to the field at position off within the * structure st. Example: *
diff --git a/src/lib/string/printf.c b/src/lib/string/printf.c
index 62758093a7..bd35b76d1b 100644
--- a/src/lib/string/printf.c
+++ b/src/lib/string/printf.c
@@ -8,9 +8,9 @@
  * \brief Compatibility wrappers around snprintf and its friends
  **/
 
+#include "lib/cc/torint.h"
 #include "lib/string/printf.h"
 #include "lib/err/torerr.h"
-#include "lib/cc/torint.h"
 #include "lib/malloc/malloc.h"
 
 #include 
@@ -45,7 +45,7 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
     return -1; /* no place for the NUL */
   if (size > SIZE_T_CEILING)
     return -1;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(HAVE_VSNPRINTF)
   r = _vsnprintf(str, size, format, args);
 #else
   r = vsnprintf(str, size, format, args);
-- 
cgit v1.2.3-54-g00ecf