]> Savannah Git Hosting - gnulib.git/commitdiff
vasnwprintf: Fix test failures on musl libc.
authorBruno Haible <bruno@clisp.org>
Mon, 20 Mar 2023 02:26:44 +0000 (03:26 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 20 Mar 2023 02:26:44 +0000 (03:26 +0100)
* m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke gl_MUSL_LIBC.
* lib/vasnprintf.c (VASNPRINTF): On musl libc, when WIDE_CHAR_VERSION,
- force pad_ourselves to be 1,
- don't use %n.
Fix zero-padding when the result starts with a prefix "0x" or "0b".
* modules/vasnwprintf (Files): Add musl.m4.
* doc/posix-functions/swprintf.texi: Mention two musl libc bugs.

ChangeLog
doc/posix-functions/swprintf.texi
lib/vasnprintf.c
m4/vasnprintf.m4
modules/vasnwprintf

index 53ba9040c60426c15065b85a3d1fcf612159b74f..e83875f2ee075d4fc7994509262e9bce89e591e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-19  Bruno Haible  <bruno@clisp.org>
+
+       vasnwprintf: Fix test failures on musl libc.
+       * m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke gl_MUSL_LIBC.
+       * lib/vasnprintf.c (VASNPRINTF): On musl libc, when WIDE_CHAR_VERSION,
+       - force pad_ourselves to be 1,
+       - don't use %n.
+       Fix zero-padding when the result starts with a prefix "0x" or "0b".
+       * modules/vasnwprintf (Files): Add musl.m4.
+       * doc/posix-functions/swprintf.texi: Mention two musl libc bugs.
+
 2023-03-19  Bruno Haible  <bruno@clisp.org>
 
        vasnwprintf: Fix module dependencies.
index 906ee521aa365960779cabbba7b8ee7233c0fec8..a87bc06c86b5e14d1d59454e5f32529c8251495e 100644 (file)
@@ -26,11 +26,21 @@ This function does not support the @samp{n} directive on some platforms:
 glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
 macOS 11.1, MSVC 14.
 @item
+This function sometimes returns a wrong value through the @samp{n} directive
+on some platforms:
+@c https://www.openwall.com/lists/musl/2023/03/19/1
+musl libc 1.2.3.
+@item
 On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and therefore cannot
 accommodate all Unicode characters.
 @item
 On Windows, this function does not take a buffer size as second argument.
 @item
+This function ignores the minimum field width in the @samp{lc} directive
+on some platforms:
+@c https://www.openwall.com/lists/musl/2023/03/20/1
+musl libc 1.2.3.
+@item
 This function does not support the @samp{b} directive, required by ISO C23,
 on some platforms:
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
index c2f10cb0c42df92855c524b8c040509919f19998..50ff2e64ddf76c0db4a933c3e5c7f841b2279096 100644 (file)
@@ -4932,7 +4932,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
               {
                 arg_type type = a.arg[dp->arg_index].type;
                 int flags = dp->flags;
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 int has_width;
 #endif
 #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
@@ -4947,7 +4947,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #else
 #               define prec_ourselves 0
 #endif
-#if NEED_PRINTF_FLAG_LEFTADJUST
+#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST
 #               define pad_ourselves 1
 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 int pad_ourselves;
@@ -4964,7 +4964,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                 TCHAR_T *tmp;
 #endif
 
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                 has_width = 0;
 #endif
 #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
@@ -4995,7 +4995,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                           width = xsum (xtimes (width, 10), *digitp++ - '0');
                         while (digitp != dp->width_end);
                       }
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                     has_width = 1;
 #endif
                   }
@@ -5050,7 +5050,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #endif
 
                 /* Decide whether to perform the padding ourselves.  */
-#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
+#if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
                 switch (dp->conversion)
                   {
 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
@@ -5210,7 +5210,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
       || (defined __APPLE__ && defined __MACH__)                            \
       || defined __OpenBSD__                                                \
       || defined __ANDROID__                                                \
-      || (defined _WIN32 && ! defined __CYGWIN__))
+      || (defined _WIN32 && ! defined __CYGWIN__))                          \
+      || (WIDE_CHAR_VERSION && MUSL_LIBC)
                 /* We can avoid passing %n and instead rely on SNPRINTF's
                    return value if
                      - !WIDE_CHAR_VERSION, because if WIDE_CHAR_VERSION,
@@ -5263,6 +5264,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
                        allows us to recognize the case of an insufficient
                        buffer size: it returns -1 in this case.  */
+                /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n
+                   on musl libc because we would run into an swprintf() bug.
+                   See <https://www.openwall.com/lists/musl/2023/03/19/1>.  */
                 fbp[1] = '\0';
 # else           /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
                 fbp[1] = '%';
@@ -5768,7 +5772,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                     /* Here count <= allocated - length.  */
 
                     /* Perform padding.  */
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                     if (pad_ourselves && has_width)
                       {
                         size_t w;
@@ -5827,6 +5831,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
                                     pad_ptr = NULL;
+                                  else
+                                    /* Do the zero-padding after the "0x" or
+                                       "0b" prefix, not before.  */
+                                    if (p - rp >= 2
+                                        && *rp == '0'
+                                        && (((dp->conversion == 'a'
+                                              || dp->conversion == 'x')
+                                             && rp[1] == 'x')
+                                            || ((dp->conversion == 'A'
+                                                 || dp->conversion == 'X')
+                                                && rp[1] == 'X')
+                                            || (dp->conversion == 'b'
+                                                && rp[1] == 'b')
+                                            || (dp->conversion == 'B'
+                                                && rp[1] == 'B')))
+                                      pad_ptr += 2;
                                 }
                               /* The generated string now extends from rp to p,
                                  with the zero padding insertion point being at
index b868aed08be8335a95973c4fe433851ac740b0ca..8e582dd791799af4d74d5bf7a562751e71036b84 100644 (file)
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 41
+# vasnprintf.m4 serial 42
 dnl Copyright (C) 2002-2004, 2006-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,
@@ -96,6 +96,7 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNWPRINTF],
 [
   AC_CHECK_FUNCS([wcsnlen mbrtowc])
   AC_CHECK_DECLS([_snwprintf], , , [[#include <stdio.h>]])
+  gl_MUSL_LIBC
   gl_PREREQ_VASNXPRINTF
 ])
 
index 6c7d63a5f6c2926186407cece31d39200255fedb..07a078696cdb460597bf4f3d8a2a0391be2d3f90 100644 (file)
@@ -21,6 +21,7 @@ m4/vasnprintf.m4
 m4/printf.m4
 m4/math_h.m4
 m4/exponentd.m4
+m4/musl.m4
 
 Depends-on:
 stdio