[tor-commits] [tor/main] Prefer use of __MINGW_PRINTF/SCANF_FORMAT if available.

ahf at torproject.org ahf at torproject.org
Mon Nov 8 14:14:49 UTC 2021


commit c93114ec9e45f4fb3843012056046eec15b875aa
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Nov 5 12:08:48 2021 -0400

    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(-)

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 <stdio.h>
 #include <stdlib.h>
@@ -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 <inttypes.h>
 
+#if defined(__MINGW32__) || defined(__MINGW64__)
+#define MINGW_ANY
+#endif
+
+#ifdef MINGW_ANY
+/* We need this for __MINGW_PRINTF_FORMAT, alas. */
+#include <stdio.h>
+#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 <b>off</b> within the
  * structure <b>st</b>.  Example:
  * <pre>
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 <stdlib.h>
@@ -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);





More information about the tor-commits mailing list