Skip to content

Commit

Permalink
[libc++] Fix return value of snprintf_l() on Windows when buffer is t…
Browse files Browse the repository at this point in the history
…oo 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
  • Loading branch information
tanderson-google committed Mar 26, 2019
1 parent b66754a commit d4d824a
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions libcxx/src/support/win32/locale_win32.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit d4d824a

Please sign in to comment.