commit c93114ec9e45f4fb3843012056046eec15b875aa Author: Nick Mathewson nickm@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);