From d4d824a861b9bed09fe1e34c0a00be0df1ec851a Mon Sep 17 00:00:00 2001 From: Thomas Anderson Date: Tue, 26 Mar 2019 19:51:30 +0000 Subject: [libc++] Fix return value of snprintf_l() on Windows when buffer is too small When the output buffer is too small to contain the output, `vsnprintf()` fills the buffer and returns the number of characters that __would have__ been written if the buffer was sufficiently large. `_vnsprintf_s()` on the other hand fills the buffer and returns -1 when this happens. We want the former behavior, but we also want to be able to pass in a locale to prevent having to call `setlocale()`. `__stdio_common_vsprintf()` is the only function general enough to get the behavior we want. Differential Revision: https://reviews.llvm.org/D59727 llvm-svn: 357024 --- libcxx/src/support/win32/locale_win32.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp index d02d7ffc3cd..ee3a4306d9e 100644 --- a/libcxx/src/support/win32/locale_win32.cpp +++ b/libcxx/src/support/win32/locale_win32.cpp @@ -87,14 +87,15 @@ int wctob_l( wint_t c, locale_t loc ) int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...) { -#if !defined(_LIBCPP_MSVCRT) - __libcpp_locale_guard __current(loc); -#endif va_list ap; va_start( ap, format ); #if defined(_LIBCPP_MSVCRT) - int result = _vsnprintf_l( ret, n, format, loc, ap ); + // FIXME: Remove usage of internal CRT function and globals. + int result = __stdio_common_vsprintf( + _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR, + ret, n, format, loc, ap); #else + __libcpp_locale_guard __current(loc); int result = vsnprintf( ret, n, format, ap ); #endif va_end(ap); -- cgit v1.2.3