From 6c0c8e0d3de28e711811f4345464c112ad64d390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 22 Jun 2015 10:23:34 +0200 Subject: [PATCH] Include fixed snprintf for Windows in platform.c Use _WIN32 to detect it rather that _MSC_VER as it turns out MSYS2 uses the broken MS version by default too. --- include/mbedtls/check_config.h | 4 ++++ include/mbedtls/config.h | 12 +++++++----- include/mbedtls/platform.h | 15 +++++++++++++++ library/platform.c | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 9fb870a72..24450319d 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -39,6 +39,10 @@ #error "mbed TLS requires a platform with 8-bit chars" #endif +#if defined(_WIN32) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_C is required on Windows" +#endif + #if defined(MBEDTLS_DEPRECATED_WARNING) && \ !defined(__GNUC__) && !defined(__clang__) #error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 1fe730c5b..33b20c04b 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -142,10 +142,7 @@ * * All these define require MBEDTLS_PLATFORM_C to be defined! * - * WARNING: MBEDTLS_PLATFORM_SNPRINTF_ALT is not available on Windows - * for compatibility reasons. - * - * WARNING: MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as * MBEDTLS_PLATFORM_XXX_MACRO! * * Uncomment a macro to enable alternate implementation of specific base @@ -2004,12 +2001,15 @@ * \def MBEDTLS_PLATFORM_C * * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit() + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). * * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned * above to be specified at runtime or compile time respectively. * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * * Module: library/platform.c * Caller: Most other .c files * @@ -2379,6 +2379,7 @@ //#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ @@ -2388,6 +2389,7 @@ //#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ /* SSL Cache options */ diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h index b71a09cf9..5dab974fd 100644 --- a/include/mbedtls/platform.h +++ b/include/mbedtls/platform.h @@ -46,8 +46,12 @@ extern "C" { #include #include #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#if defined(_WIN32) +#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ +#else #define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ #endif +#endif #if !defined(MBEDTLS_PLATFORM_STD_PRINTF) #define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */ #endif @@ -150,7 +154,18 @@ int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); /* * The function pointers for snprintf + * + * The snprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. */ +#if defined(_WIN32) +/* For Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); +#endif + #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); diff --git a/library/platform.c b/library/platform.c index 123267a8a..23dba94f5 100644 --- a/library/platform.c +++ b/library/platform.c @@ -63,6 +63,21 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), } #endif /* MBEDTLS_PLATFORM_MEMORY */ +#if defined(_WIN32) +#include +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) +{ + int ret; + va_list argp; + + va_start( argp, fmt ); + ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); + va_end( argp ); + + return( ret ); +} +#endif + #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) /*