From: Bruno Haible Date: Mon, 12 Jun 2023 16:39:49 +0000 (+0200) Subject: vasnwprintf-posix: Work around another musl libc bug. X-Git-Tag: v1.0~1215 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=94a7cdb7496bfd7d44ac26938ecd219c75ce6f34;p=gnulib.git vasnwprintf-posix: Work around another musl libc bug. * m4/printf.m4 (gl_SWPRINTF_DIRECTIVE_LC): New macro. * m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke it, and set NEED_WPRINTF_DIRECTIVE_LC if the %lc test failed. * lib/vasnprintf.c (VASNPRINTF): If NEED_WPRINTF_DIRECTIVE_LC is set, do the processing for %lc and %ls ourselves. (local_wcslen): Update condition. * doc/posix-functions/swprintf.texi: Mention the %lc problem. --- diff --git a/ChangeLog b/ChangeLog index aebce47f42..e2eb7e6faa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2023-06-12 Bruno Haible + + vasnwprintf-posix: Work around another musl libc bug. + * m4/printf.m4 (gl_SWPRINTF_DIRECTIVE_LC): New macro. + * m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke it, and set + NEED_WPRINTF_DIRECTIVE_LC if the %lc test failed. + * lib/vasnprintf.c (VASNPRINTF): If NEED_WPRINTF_DIRECTIVE_LC is set, do + the processing for %lc and %ls ourselves. + (local_wcslen): Update condition. + * doc/posix-functions/swprintf.texi: Mention the %lc problem. + 2023-06-12 Bruno Haible vasnwprintf-posix: Work around a musl libc bug. diff --git a/doc/posix-functions/swprintf.texi b/doc/posix-functions/swprintf.texi index 68578e016b..7883bfbe44 100644 --- a/doc/posix-functions/swprintf.texi +++ b/doc/posix-functions/swprintf.texi @@ -74,6 +74,9 @@ In the C or POSIX locales, the @code{%c} and @code{%s} conversions may fail on some platforms: glibc 2.35, musl libc 1.2.4, FreeBSD 13.2, NetBSD 9.3, OpenBSD 7.2, Cygwin 2.9.0. @item +The @code{%lc} directive may fail on some platforms: +musl libc 1.2.4, FreeBSD 13.2, NetBSD 9.3, OpenBSD 7.2. +@item When formatting an integer with grouping flag, this function inserts thousands separators even in the "C" locale on some platforms: NetBSD 5.1. diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 63a6cd60f3..9ad31b2a08 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -247,7 +247,7 @@ local_strnlen (const char *string, size_t maxlen) # endif #endif -#if (((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T +#if (((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T # if HAVE_WCSLEN # define local_wcslen wcslen # else @@ -2765,14 +2765,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } #endif -#if WIDE_CHAR_VERSION && !DCHAR_IS_TCHAR +#if WIDE_CHAR_VERSION && (!DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) else if ((dp->conversion == 's' && a.arg[dp->arg_index].type == TYPE_WIDE_STRING) || (dp->conversion == 'c' && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)) { /* %ls or %lc in vasnwprintf. See the specification of - fwprintf. */ + fwprintf. */ /* It would be silly to use snprintf ("%ls", ...) and then convert back the result from a char[] to a wchar_t[]. Instead, just copy the argument wchar_t[] to the result. */ diff --git a/m4/printf.m4 b/m4/printf.m4 index 509f3affb7..8b8f01067f 100644 --- a/m4/printf.m4 +++ b/m4/printf.m4 @@ -1,4 +1,4 @@ -# printf.m4 serial 83 +# printf.m4 serial 84 dnl Copyright (C) 2003, 2007-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -2009,6 +2009,52 @@ int main () ]) ]) +dnl Test whether the *wprintf family of functions supports the 'lc' conversion +dnl specifier for all wide characters. +dnl (ISO C11, POSIX:2001) +dnl Result is gl_cv_func_swprintf_directive_lc. + +AC_DEFUN([gl_SWPRINTF_DIRECTIVE_LC], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether swprintf supports the 'lc' directive], + [gl_cv_func_swprintf_directive_lc], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static wchar_t buf[100]; +static wint_t L_invalid = (wchar_t) 0x76543210; +int main () +{ + int result = 0; + /* This catches a musl libc 1.2.4, Android bug. + Reported at . */ + if (swprintf (buf, sizeof (buf) / sizeof (wchar_t), + L"%lc %d", L_invalid, 33, 44, 55) < 0) + result |= 1; + return result; +}]])], + [gl_cv_func_swprintf_directive_lc=yes], + [gl_cv_func_swprintf_directive_lc=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_swprintf_directive_lc="guessing yes";; + # Guess no on musl systems. + *-musl* | midipix*) gl_cv_func_swprintf_directive_lc="guessing no";; + # Guess no on Android. + linux*-android*) gl_cv_func_swprintf_directive_lc="guessing no";; + # Guess yes on native Windows. + mingw*) gl_cv_func_swprintf_directive_lc="guessing yes";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_swprintf_directive_lc="$gl_cross_guess_normal";; + esac + ]) + ]) +]) + dnl The results of these tests on various platforms are: dnl dnl 1 = gl_PRINTF_SIZES_C99 @@ -2037,6 +2083,7 @@ dnl 23 = gl_SNPRINTF_SIZE1 dnl 24 = gl_VSNPRINTF_ZEROSIZE_C99 dnl 25 = gl_SWPRINTF_WORKS dnl 26 = gl_SWPRINTF_DIRECTIVE_LA +dnl 27 = gl_SWPRINTF_DIRECTIVE_LC dnl dnl 1 = checking whether printf supports size specifiers as in C99... dnl 2 = checking whether printf supports size specifiers as in C23... @@ -2064,47 +2111,48 @@ dnl 23 = checking whether snprintf respects a size of 1... dnl 24 = checking whether vsnprintf respects a zero size as in C99... dnl 25 = checking whether swprintf works... dnl 26 = checking whether swprintf supports the 'La' and 'LA' directives... +dnl 27 = checking whether swprintf supports the 'lc' directive... dnl dnl . = yes, # = no. dnl -dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 -dnl musl libc 1.2.3 . # . . . . # # . . . . . . . . . . . . . . . . # . -dnl glibc 2.35 . # . . . . . . . . . # . . . . . . . . . . . . . . -dnl glibc 2.5 . # . . . . # # . . . # . . . . . . . . . . . . . # -dnl glibc 2.3.6 . # . . . # # # . . . # . . . . . . . . . . . . . # -dnl FreeBSD 13.0 . # . . . # # # . . . # . . . . . # . . . . . . # . -dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . # . . . # . # . . . . . . # ? -dnl Mac OS X 10.13.5 . # . . # # # # . # . # . . . . . . . . . # . . # ? -dnl Mac OS X 10.5.8 . # . . # # # # . . . # . . . # . . . . . . . . # ? -dnl Mac OS X 10.3.9 . # . . . # # # . . . # . . . # . # . . . . . . # ? -dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . # . . . . . # . . . . . . # . -dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # # . # . # . # . . . . . . # ? -dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . . . . ? . . . . . . ? ? -dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . . . . # . . . . . . ? ? -dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # . # # # . . . . . . ? ? -dnl Solaris 11.4 . # . # # # # # . . # # . . . # . . . . . . . . . ? -dnl Solaris 11.3 . # . . . # # # . . # # . . . . . . . . . . . . . ? -dnl Solaris 11.0 . # . # # # # # . . # # . . . # . . . . . . . . ? ? -dnl Solaris 10 . # . # # # # # . . # # . . . # # . . . . . . . ? ? -dnl Solaris 2.6 ... 9 # # . # # # # # # . # # . . . # # . . . # . . . ? ? -dnl Solaris 2.5.1 # # . # # # # # # . # # . . . # . . # # # # # # ? ? -dnl AIX 7.1 . # . # # # # # . . . # . . . # # . . . . . . . # . -dnl AIX 5.2 . # . # # # # # . . . # . . . # . . . . . . . . # ? -dnl AIX 4.3.2, 5.1 # # . # # # # # # . . # . . . # . . . . # . . . # ? -dnl HP-UX 11.31 . # . . . # # # . . . ? . . . # . . . . # # . . ? ? -dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . . # . . . . # # . # ? ? -dnl HP-UX 10.20 # # . # . # # # # . ? ? . . # # . . . . # # ? # ? ? -dnl IRIX 6.5 # # . # # # # # # . # # . . . # . . . . # . . . # ? -dnl OSF/1 5.1 # # . # # # # # # . . ? . . . # . . . . # . . # ? ? -dnl OSF/1 4.0d # # . # # # # # # . . ? . . . # . . # # # # # # ? ? -dnl NetBSD 9.0 . # . . . # # # . . . # . . . . . . . . . . . . # . -dnl NetBSD 5.0 . # . . # # # # . . . # . . . # . # . . . . . . # ? -dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? # . ? ? ? ? ? . . . ? ? ? # ? -dnl NetBSD 3.0 . # . . . # # # # . ? # # # ? # . # . . . . . . # ? -dnl Haiku . # . . # # # # # . # ? . . . . . ? . . ? . . . . # -dnl BeOS # # # . # # # # # . ? ? # . ? . # ? . . ? . . . ? ? -dnl Android 4.3 . # . # # # # # # # # ? . # . # . # . . . # . . ? ? -dnl old mingw / msvcrt # # # # # # # # # . . ? # # . # # ? . # # # . . # ? -dnl MSVC 9 # # # # # # # # # # . ? # # . # # ? # # # # . . # ? -dnl mingw 2009-2011 . # # . # . # # . . . ? # # . . . ? . . . . . . # ? -dnl mingw-w64 2011 # # # # # # # # # . . ? # # . # # ? . # # # . . # ? +dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 +dnl musl libc 1.2.3 . # . . . . # # . . . . . . . . . . . . . . . . # . # +dnl glibc 2.35 . # . . . . . . . . . # . . . . . . . . . . . . . . . +dnl glibc 2.5 . # . . . . # # . . . # . . . . . . . . . . . . . # . +dnl glibc 2.3.6 . # . . . # # # . . . # . . . . . . . . . . . . . # . +dnl FreeBSD 13.0 . # . . . # # # . . . # . . . . . # . . . . . . # . # +dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . # . . . # . # . . . . . . # ? ? +dnl Mac OS X 10.13.5 . # . . # # # # . # . # . . . . . . . . . # . . # ? ? +dnl Mac OS X 10.5.8 . # . . # # # # . . . # . . . # . . . . . . . . # ? ? +dnl Mac OS X 10.3.9 . # . . . # # # . . . # . . . # . # . . . . . . # ? ? +dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . # . . . . . # . . . . . . # . # +dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # # . # . # . # . . . . . . # ? ? +dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . . . . ? . . . . . . ? ? ? +dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . . . . # . . . . . . ? ? ? +dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # . # # # . . . . . . ? ? ? +dnl Solaris 11.4 . # . # # # # # . . # # . . . # . . . . . . . . . # . +dnl Solaris 11.3 . # . . . # # # . . # # . . . . . . . . . . . . . # . +dnl Solaris 11.0 . # . # # # # # . . # # . . . # . . . . . . . . ? ? ? +dnl Solaris 10 . # . # # # # # . . # # . . . # # . . . . . . . . # . +dnl Solaris 2.6 ... 9 # # . # # # # # # . # # . . . # # . . . # . . . ? ? ? +dnl Solaris 2.5.1 # # . # # # # # # . # # . . . # . . # # # # # # ? ? ? +dnl AIX 7.1 . # . # # # # # . . . # . . . # # . . . . . . . # . . +dnl AIX 5.2 . # . # # # # # . . . # . . . # . . . . . . . . # ? ? +dnl AIX 4.3.2, 5.1 # # . # # # # # # . . # . . . # . . . . # . . . # ? ? +dnl HP-UX 11.31 . # . . . # # # . . . ? . . . # . . . . # # . . ? ? ? +dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . . # . . . . # # . # ? ? ? +dnl HP-UX 10.20 # # . # . # # # # . ? ? . . # # . . . . # # ? # ? ? ? +dnl IRIX 6.5 # # . # # # # # # . # # . . . # . . . . # . . . # ? ? +dnl OSF/1 5.1 # # . # # # # # # . . ? . . . # . . . . # . . # ? ? ? +dnl OSF/1 4.0d # # . # # # # # # . . ? . . . # . . # # # # # # ? ? ? +dnl NetBSD 9.0 . # . . . # # # . . . # . . . . . . . . . . . . # . # +dnl NetBSD 5.0 . # . . # # # # . . . # . . . # . # . . . . . . # ? ? +dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? # . ? ? ? ? ? . . . ? ? ? # ? ? +dnl NetBSD 3.0 . # . . . # # # # . ? # # # ? # . # . . . . . . # ? ? +dnl Haiku . # . . # # # # # . # ? . . . . . ? . . ? . . . . # . +dnl BeOS # # # . # # # # # . ? ? # . ? . # ? . . ? . . . ? ? ? +dnl Android 4.3 . # . # # # # # # # # ? . # . # . # . . . # . . ? ? ? +dnl old mingw / msvcrt # # # # # # # # # . . ? # # . # # ? . # # # . . # ? ? +dnl MSVC 9 # # # # # # # # # # . ? # # . # # ? # # # # . . # ? ? +dnl mingw 2009-2011 . # # . # . # # . . . ? # # . . . ? . . . . . . # ? ? +dnl mingw-w64 2011 # # # # # # # # # . . ? # # . # # ? . # # # . . # ? ? diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 index b733f9a848..df87b9e798 100644 --- a/m4/vasnprintf.m4 +++ b/m4/vasnprintf.m4 @@ -166,6 +166,15 @@ int main() the 'a' directive with 'long double' arguments.]) ;; esac + gl_SWPRINTF_DIRECTIVE_LC + case "$gl_cv_func_swprintf_directive_lc" in + *yes) ;; + *) + AC_DEFINE([NEED_WPRINTF_DIRECTIVE_LC], [1], + [Define if the vasnwprintf implementation needs special code for + the 'lc' directive.]) + ;; + esac gl_MUSL_LIBC gl_PREREQ_VASNXPRINTF ])