From 21718add2560a3103b881327bee3779b06a488ff Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Wed, 3 Jul 2019 21:49:42 +0100 Subject: [PATCH] Avoid built-in snprintf() prototypes; fix MinGW-Bug #39224 --- mingwrt/ChangeLog | 17 ++++++++++++++++ mingwrt/include/stdio.h | 43 +++++++++++++++++++++++++++++++++++---- mingwrt/mingwex/stdio/snprintf.c | 40 ++++++++++++++++++++++++++---------- mingwrt/mingwex/stdio/vsnprintf.c | 40 ++++++++++++++++++++++++++---------- mingwrt/tests/ansiprintf.at | 35 +++++++++++++++++-------------- 5 files changed, 134 insertions(+), 41 deletions(-) diff --git a/mingwrt/ChangeLog b/mingwrt/ChangeLog index 45aa8ab..61ec093 100644 --- a/mingwrt/ChangeLog +++ b/mingwrt/ChangeLog @@ -1,3 +1,20 @@ +2019-07-03 Keith Marshall + + Avoid built-in snprintf() prototypes; fix MinGW-Bug #39224 + + * include/stdio.h [__USE_MINGW_ANSI_STDIO] + (snprintf, vsnprintf): Implement them in-line, delegating to... + (__mingw_vsnprintf): ...this external function. + + * mingwex/stdio/snprintf.c mingwex/stdio/vsnprintf.c: Assert + copyright; include , instead of , to obtain a + definition of "size_t"; this is required because the new in-line + prototypes, now provided in , conflict with the intent + to provide external implementations. + + * tests/ansiprintf.at (MINGW_AT_CHECK_SNPRINTF): Conditionally + circumvent conditions which may produce -Wformat warnings. + 2019-07-01 Keith Marshall Revert to macro implementation of "alloca()" functions. diff --git a/mingwrt/include/stdio.h b/mingwrt/include/stdio.h index 4ab5cca..8ee3624 100644 --- a/mingwrt/include/stdio.h +++ b/mingwrt/include/stdio.h @@ -375,7 +375,7 @@ extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const char*, __VAL */ extern unsigned int _mingw_output_format_control( unsigned int, unsigned int ); -#if __USE_MINGW_ANSI_STDIO +#if __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE /* User has expressed a preference for C99 conformance... */ # undef __mingw_stdio_redirect__ @@ -393,12 +393,20 @@ extern unsigned int _mingw_output_format_control( unsigned int, unsigned int ); */ # define __mingw_stdio_redirect__ static __inline__ __cdecl __MINGW_NOTHROW -# else +# else /* Neither C++ nor __GNUC__ */ /* Can't use inlines; fall back on module local static stubs. */ # define __mingw_stdio_redirect__ static __cdecl __MINGW_NOTHROW -# endif +# endif /* Neither C++ nor __GNUC__ */ +#endif /* __USE_MINGW_ANSI_STDIO || defined _ISOC99_SOURCE */ + +#if __USE_MINGW_ANSI_STDIO +/* The MinGW ISO-C conforming implementations of the printf() family + * of functions are to be used, in place of non-conforming Microsoft + * implementations; force call redirection, via the following set of + * in-line functions. + */ __mingw_stdio_redirect__ int fprintf (FILE *__stream, const char *__format, ...) { @@ -457,7 +465,34 @@ _CRTIMP __cdecl __MINGW_NOTHROW int vfprintf (FILE *, const char *, __VALIST); _CRTIMP __cdecl __MINGW_NOTHROW int vprintf (const char *, __VALIST); _CRTIMP __cdecl __MINGW_NOTHROW int vsprintf (char *, const char *, __VALIST); -#endif +#endif /* !__USE_MINGW_ANSI_STDIO */ + +#if __GNUC__ && defined _ISOC99_SOURCE +/* Although MinGW implementations of the ISO-C99 snprintf() and + * vsnprintf() functions do not conflict with any implementation + * in MSVCRT.DLL, (because MSVCRT.DLL does not implement either), + * there are -Wformat attribute conflicts with the GCC built-in + * prototypes associated with each; by providing the following + * in-line function implementations, which will override GCC's + * built-in prototypes, we may avoid these conflicts. + */ +__mingw_stdio_redirect__ +int snprintf (char *__buf, size_t __len, const char *__format, ...) +{ + register int __retval; + __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format ); + __retval = __mingw_vsnprintf( __buf, __len, __format, __local_argv ); + __builtin_va_end( __local_argv ); + return __retval; +} + +__mingw_stdio_redirect__ +int vsnprintf (char *__buf, size_t __len, const char *__format, __VALIST __local_argv) +{ + return __mingw_vsnprintf( __buf, __len, __format, __local_argv ); +} +#endif /* __GNUC__ && defined _ISOC99_SOURCE */ + /* Regardless of user preference, always offer these alternative * entry points, for direct access to the MSVCRT implementations, * with ms_printf -Wformat checking in each case. diff --git a/mingwrt/mingwex/stdio/snprintf.c b/mingwrt/mingwex/stdio/snprintf.c index e04100d..1165d4c 100644 --- a/mingwrt/mingwex/stdio/snprintf.c +++ b/mingwrt/mingwex/stdio/snprintf.c @@ -10,21 +10,39 @@ * standard MSVCRT function remains available, and may be invoked * directly, using this fully qualified form of its name). * - * Written by Keith Marshall + * Written by Keith Marshall + * Copyright (C) 2008, 2019, MinGW.org Project * - * This is free software. You may redistribute and/or modify it as you - * see fit, without restriction of copyright. + * This replaces earlier, substantially different implementations, + * originally provided as snprintf.c, and later encapsulated within + * gdtoa/mingw_snprintf.c: * - * This software is provided "as is", in the hope that it may be useful, - * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of - * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no - * time will the author accept any form of liability for any damages, - * however caused, resulting from the use of this software. + * Written by Danny Smith + * Copyright (C) 2002, 2003, 2007, 2008, MinGW.org Project + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice, this permission notice, and the following + * disclaimer shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS IN THE SOFTWARE. * */ - -#include #include +#include #include "pformat.h" @@ -41,4 +59,4 @@ int __cdecl __snprintf( char *buf, size_t length, const char *fmt, ... ) return retval; } -/* $RCSfile$$Revision$: end of file */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/stdio/vsnprintf.c b/mingwrt/mingwex/stdio/vsnprintf.c index b96b7e1..1def294 100644 --- a/mingwrt/mingwex/stdio/vsnprintf.c +++ b/mingwrt/mingwex/stdio/vsnprintf.c @@ -10,21 +10,39 @@ * standard MSVCRT function remains available, and may be invoked * directly, using this fully qualified form of its name). * - * Written by Keith Marshall + * Written by Keith Marshall + * Copyright (C) 2008, 2019, MinGW.org Project * - * This is free software. You may redistribute and/or modify it as you - * see fit, without restriction of copyright. + * This replaces earlier, substantially different implementations, + * originally provided as vsnprintf.c, and later encapsulated within + * gdtoa/mingw_snprintf.c: * - * This software is provided "as is", in the hope that it may be useful, - * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of - * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no - * time will the author accept any form of liability for any damages, - * however caused, resulting from the use of this software. + * Written by Danny Smith + * Copyright (C) 2002, 2003, 2007, 2008, MinGW.org Project + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice, this permission notice, and the following + * disclaimer shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS IN THE SOFTWARE. * */ - -#include #include +#include #include "pformat.h" @@ -52,4 +70,4 @@ int __cdecl __vsnprintf( char *buf, size_t length, const char *fmt, va_list argv return retval; } -/* $RCSfile$$Revision$: end of file */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/tests/ansiprintf.at b/mingwrt/tests/ansiprintf.at index 65cbc30..6486637 100644 --- a/mingwrt/tests/ansiprintf.at +++ b/mingwrt/tests/ansiprintf.at @@ -249,26 +249,31 @@ MINGW_AT_CHECK_PRINTF([[%16.0La%4d]], [1.450L, 44], [:: 0xcp-3 44::]) MINGW_AT_CHECK_PRINTF([[%16.1La%4d]], [1.999L, 99], [:: 0x8.0p-2 99::]) -# MINGW_AT_CHECK_SNPRINTF( FORMAT, MAXCOUNT, INITCOUNT ) -# ------------------------------------------------------ +# MINGW_AT_CHECK_SNPRINTF( FORMAT, COUNT, MAXCOUNT, INITCOUNT ) +# ------------------------------------------------------------- # Test the behaviour of the snprintf() function, with respect to # output truncation at specified MAXCOUNT (no more than 32), when # writing string "Sample text; sufficient buffer" subject to the -# specified. Also supports testing the effect of "%n" counting -# on an internal integer variable, initialized to INITCOUNT. +# specified FORMAT and COUNT (concatenated to define the format +# string). Also supports testing the effect of "%n" counting on +# an internal integer variable, initialized to INITCOUNT, when +# COUNT is specified as "n", (with optional "hh" length modifier +# prefix; if this option is not to be exercised, FORMAT should +# be passed as "%", with COUNT as "s"). # m4_define([MINGW_AT_CHECK_SNPRINTF],[dnl -AT_SETUP([snprintf (output, $2, "$1", ...)]) -AT_KEYWORDS([C printf])MINGW_AT_DATA_CRLF([expout],[[$4 +AT_SETUP([snprintf (output, $3, "$1$2", ...)]) +AT_KEYWORDS([C printf])MINGW_AT_DATA_CRLF([expout],[[$5 ]])MINGW_AT_CHECK_RUN([[[ #define _XOPEN_SOURCE 700 #include int main() -{ char output[32]; int capture = ]$3[; +{ char output[32]; union { int n; char hhn; } capture = {]$4[}; const char *sample = "Sample text; sufficient buffer"; - int total = snprintf (output, ]$2[, "]$1[", sample, &capture); - snprintf (NULL, 0, "]$1[", output, &capture); - printf ("%s: %d required; %d captured\n", output, total, capture); + int total = snprintf (output, ]$3[, "]$1$2[", sample]m4_if([$2],[s],]dnl + [,[, &capture.$2])[); + snprintf (NULL, 0, "]$1$2[", output]m4_if([$2],[s],,[, &capture.$2])[); + printf ("%s: %d required; %d captured\n", output, total, capture.n); return 0; }]]],,[expout])dnl AT_CLEANUP @@ -278,20 +283,20 @@ AT_CLEANUP # Tests for snprintf() with limited length internal buffer. # AT_BANNER([ISO-C99 snprintf() buffer length control.]) -MINGW_AT_CHECK_SNPRINTF([[%s]],[32],[1024],dnl +MINGW_AT_CHECK_SNPRINTF([[%]],[s],[32],[1024],dnl [Sample text; sufficient buffer: 30 required; 1024 captured]) -MINGW_AT_CHECK_SNPRINTF([[%s]],[12],[1024],dnl +MINGW_AT_CHECK_SNPRINTF([[%]],[s],[12],[1024],dnl [Sample text: 30 required; 1024 captured]) # Tests for effect of "%n" output length counting. # AT_BANNER([ISO-C99 snprintf() intermediate output counting.]) -MINGW_AT_CHECK_SNPRINTF([[%s%n]],[32],[1024],dnl +MINGW_AT_CHECK_SNPRINTF([[%s%]],[n],[32],[1024],dnl [Sample text; sufficient buffer: 30 required; 30 captured]) -MINGW_AT_CHECK_SNPRINTF([[%s%n]],[12],[1024],dnl +MINGW_AT_CHECK_SNPRINTF([[%s%]],[n],[12],[1024],dnl [Sample text: 30 required; 11 captured]) -MINGW_AT_CHECK_SNPRINTF([[%s%hhn]],[12],[1024],dnl +MINGW_AT_CHECK_SNPRINTF([[%s%]],[hhn],[12],[1024],dnl [Sample text: 30 required; 1035 captured]) # vim: filetype=config formatoptions=croql -- 2.11.0