mirror of
https://git.code.sf.net/p/mingw-w64/mingw-w64
synced 2024-11-23 01:44:43 +08:00
crt: Fix non-ISO (v)snwprintf() functions when __USE_MINGW_ANSI_STDIO=0
ISO C does not define (v)snwprintf() function. But ISO C11 in optional Appendix K defines (v)snwprintf_s() function which has same behavior as non-wide ISO C11 Appendix K (v)snprintf_s() function (which is secure variant of (v)snprintf()). Function (v)snwprintf() is not provided by any MS CRT library and neither by any MS header file. mingw32 runtime and mingw-w64 runtime since beginning provide function named (v)snwprintf (without leading underscore) and define it under symbol name __mingw_(v)snwprintf. This function differs from ISO C (v)swprintf() just in return value. ISO C (v)swprintf() when buffer is too small returns negative value but this (v)snwprintf() returns size of buffer in wide characters, similarly to non-wide ISO C (v)snprintf() function, and also similarly to ISO C11 Annex K (v)snwprintf_s(). This non-ISO (v)snwprintf() and both ISO C (v)snwprintf_s() and (v)snprintf() always fill trailing nul character. But when __USE_MINGW_ANSI_STDIO=0 the (v)snwprintf() is redirected to __ms_(v)snwprintf() function, which is just wrapper around msvcrt _vsnwprintf() function. And msvcrt _vsnwprintf() function does not fill trailing nul character and does not return required buffer size when output buffer is too small. So fix __ms_(v)snwprintf() functions to properly fill trailing nul character and return required size of bufer, like ISO C vsnprintf(). Also adjust header files and remove wrong symbol aliases for (v)snwprintf symbols from def files. This will make API of (v)snwprintf() function compatible for both __USE_MINGW_ANSI_STDIO=0 and __USE_MINGW_ANSI_STDIO=1 modes and also to mimics API of ISO C (v)snwprintf_s() function. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
c85d64d8cb
commit
c50df03570
@ -172,9 +172,11 @@ src_msvcrt_common=\
|
||||
stdio/acrt_iob_func.c \
|
||||
stdio/strtof.c \
|
||||
stdio/snprintf_alias.c \
|
||||
stdio/snwprintf_alias.c \
|
||||
stdio/swprintf.c \
|
||||
stdio/swprintf_alias.c \
|
||||
stdio/vsnprintf_alias.c \
|
||||
stdio/vsnwprintf_alias.c \
|
||||
stdio/vswprintf.c \
|
||||
stdio/vswprintf_alias.c \
|
||||
math/cbrt.c math/cbrtf.c \
|
||||
|
@ -1926,8 +1926,3 @@ F_I386(_libm_sse2_tan_precise)
|
||||
#define USE_WCSTOK_S_FOR_WCSTOK
|
||||
#endif
|
||||
#include "crt-aliases.def.in"
|
||||
|
||||
; This is list of additional symbol aliases not available in any CRT library
|
||||
; FIXME: check if these really are needed
|
||||
snwprintf == _snwprintf
|
||||
vsnwprintf == _vsnwprintf
|
||||
|
@ -2233,8 +2233,6 @@ vfwscanf
|
||||
vfwscanf_s
|
||||
vprintf
|
||||
vprintf_s
|
||||
snwprintf == _snwprintf
|
||||
vsnwprintf == _vsnwprintf
|
||||
vscanf
|
||||
vscanf_s
|
||||
vsprintf
|
||||
|
@ -2300,8 +2300,6 @@ vfwscanf
|
||||
vfwscanf_s
|
||||
vprintf
|
||||
vprintf_s
|
||||
snwprintf == _snwprintf
|
||||
vsnwprintf == _vsnwprintf
|
||||
vscanf
|
||||
vscanf_s
|
||||
vsprintf
|
||||
|
@ -1592,8 +1592,6 @@ _vsnprintf_c_l
|
||||
_vsnprintf_l
|
||||
_vsnprintf_s
|
||||
_vsnprintf_s_l
|
||||
snwprintf == _snwprintf
|
||||
vsnwprintf == _vsnwprintf
|
||||
_vsnwprintf
|
||||
_vsnwprintf_l
|
||||
_vsnwprintf_s
|
||||
|
@ -1651,8 +1651,6 @@ _vsnprintf_c_l
|
||||
_vsnprintf_l
|
||||
_vsnprintf_s
|
||||
_vsnprintf_s_l
|
||||
snwprintf == _snwprintf
|
||||
vsnwprintf == _vsnwprintf
|
||||
_vsnwprintf
|
||||
_vsnwprintf_l
|
||||
_vsnwprintf_s
|
||||
|
@ -12,7 +12,7 @@ int __cdecl __ms_snwprintf(wchar_t *buffer, size_t n, const wchar_t *format, ...
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, format);
|
||||
retval = _vsnwprintf(buffer, n, format, argptr);
|
||||
retval = __ms_vsnwprintf(buffer, n, format, argptr);
|
||||
va_end(argptr);
|
||||
return retval;
|
||||
}
|
||||
|
26
mingw-w64-crt/stdio/snwprintf_alias.c
Normal file
26
mingw-w64-crt/stdio/snwprintf_alias.c
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Intentionally not including stdio.h, as it unconditionally defines the
|
||||
* swprintf inline, and it can't be renamed with "#define snwprintf othername"
|
||||
* either, as stdio.h contains "#undef snwprintf". */
|
||||
|
||||
int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t *format, va_list arg);
|
||||
|
||||
int __cdecl snwprintf(wchar_t *buffer, size_t n, const wchar_t *format, ...);
|
||||
int __cdecl snwprintf(wchar_t *buffer, size_t n, const wchar_t *format, ...)
|
||||
{
|
||||
int retval;
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, format);
|
||||
retval = __ms_vsnwprintf(buffer, n, format, argptr);
|
||||
va_end(argptr);
|
||||
return retval;
|
||||
}
|
@ -12,5 +12,23 @@ int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t * format,
|
||||
|
||||
int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t * format, va_list argptr)
|
||||
{
|
||||
return _vsnwprintf(buffer, n, format, argptr);
|
||||
int retval;
|
||||
|
||||
/* _vsnwprintf() does not work with zero length buffer
|
||||
* so count number of characters by _vscwprintf() call */
|
||||
if (n == 0)
|
||||
return _vscwprintf(format, argptr);
|
||||
|
||||
retval = _vsnwprintf(buffer, n, format, argptr);
|
||||
|
||||
/* _vsnwprintf() does not fill trailing null character if there is not place for it */
|
||||
if (retval < 0 || (size_t)retval == n)
|
||||
buffer[n-1] = '\0';
|
||||
|
||||
/* _vsnwprintf() returns negative number if buffer is too small
|
||||
* so count number of characters by _vscwprintf() call */
|
||||
if (retval < 0)
|
||||
retval = _vscwprintf(format, argptr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
20
mingw-w64-crt/stdio/vsnwprintf_alias.c
Normal file
20
mingw-w64-crt/stdio/vsnwprintf_alias.c
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Intentionally not including stdio.h, as it unconditionally defines the
|
||||
* vswprintf inline, and it can't be renamed with "#define vsnwprintf othername"
|
||||
* either, as stdio.h contains "#undef vsnwprintf". */
|
||||
|
||||
int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t *format, va_list argptr);
|
||||
|
||||
int __cdecl vsnwprintf(wchar_t *buffer, size_t n, const wchar_t *format, va_list argptr);
|
||||
int __cdecl vsnwprintf(wchar_t *buffer, size_t n, const wchar_t *format, va_list argptr)
|
||||
{
|
||||
return __ms_vsnwprintf(buffer, n, format, argptr);
|
||||
}
|
@ -1235,7 +1235,7 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builti
|
||||
}
|
||||
|
||||
__mingw_ovr
|
||||
int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...)
|
||||
int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...)
|
||||
{
|
||||
__builtin_va_list __ap;
|
||||
int __ret;
|
||||
@ -1247,8 +1247,7 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builti
|
||||
__mingw_ovr
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg)
|
||||
{
|
||||
int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, s, n, format, NULL, arg);
|
||||
return __ret < 0 ? -1 : __ret;
|
||||
return __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1287,21 +1286,8 @@ int vsnwprintf (wchar_t *__stream, size_t __n, const wchar_t *__format, __builti
|
||||
#if __USE_MINGW_ANSI_STDIO == 0
|
||||
int __cdecl __ms_snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...);
|
||||
int __cdecl __ms_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , va_list);
|
||||
__mingw_ovr
|
||||
int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list argp;
|
||||
__builtin_va_start (argp, format);
|
||||
r = _vsnwprintf (s, n, format, argp);
|
||||
__builtin_va_end (argp);
|
||||
return r;
|
||||
}
|
||||
__mingw_ovr
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg)
|
||||
{
|
||||
return _vsnwprintf(s,n,format,arg);
|
||||
}
|
||||
int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...) __MINGW_ASM_CALL(__ms_snwprintf);
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg) __MINGW_ASM_CALL(__ms_vsnwprintf);
|
||||
#endif
|
||||
|
||||
#endif /* ! __NO_ISOCEXT */
|
||||
|
@ -759,12 +759,12 @@ __MINGW_ASM_CALL(__mingw_vsnwprintf);
|
||||
__builtin_va_start(__ap, format);
|
||||
__ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, __ap);
|
||||
__builtin_va_end(__ap);
|
||||
return __ret;
|
||||
return __ret < 0 ? -1 : __ret;
|
||||
}
|
||||
__mingw_ovr
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg)
|
||||
{
|
||||
int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, s, n, format, NULL, arg);
|
||||
int __ret = __stdio_common_vswprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, s, n, format, NULL, arg);
|
||||
return __ret < 0 ? -1 : __ret;
|
||||
}
|
||||
#endif
|
||||
@ -786,21 +786,8 @@ __MINGW_ASM_CALL(__mingw_vsnwprintf);
|
||||
# undef vsnwprintf
|
||||
int __cdecl __ms_snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...);
|
||||
int __cdecl __ms_vsnwprintf (wchar_t * __restrict__ , size_t, const wchar_t * __restrict__ , va_list);
|
||||
__mingw_ovr
|
||||
int snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list argp;
|
||||
__builtin_va_start (argp, format);
|
||||
r = _vsnwprintf (s, n, format, argp);
|
||||
__builtin_va_end (argp);
|
||||
return r;
|
||||
}
|
||||
__mingw_ovr
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg)
|
||||
{
|
||||
return _vsnwprintf(s,n,format,arg);
|
||||
}
|
||||
int __cdecl snwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, ...) __MINGW_ASM_CALL(__ms_snwprintf);
|
||||
int __cdecl vsnwprintf (wchar_t * __restrict__ s, size_t n, const wchar_t * __restrict__ format, va_list arg) __MINGW_ASM_CALL(__ms_vsnwprintf);
|
||||
#pragma pop_macro ("vsnwprintf")
|
||||
#pragma pop_macro ("snwprintf")
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user