bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

unistdio/u*-vasnprintf: Fix conversion of %Id directive result


From: Bruno Haible
Subject: unistdio/u*-vasnprintf: Fix conversion of %Id directive result
Date: Wed, 22 Mar 2023 06:19:47 +0100

In the conversion from TCHAR_T[] to DCHAR_T[] in vasnprintf.c, there is an
optimized loop for the case that the directive's result is entirely ASCII.

There was a bug in this logic: On glibc systems, the result of the %Id
directive uses alternate digits (used in Farsi and some Arabic locales),
and these are not ASCII.

I found this by running the vasnwprintf unit test (test-vasnwprintf-posix3)
in a testdir configured with ac_cv_func_swprintf=no. The code paths for
the case of vasnwprintf on old platforms and of unistdio/u*-vasnprintf are
similar.


2023-03-21  Bruno Haible  <bruno@clisp.org>

        unistdio/u*-vasnprintf: Fix conversion of %Id directive result.
        * lib/vasnprintf.c (VASNPRINTF): Don't assume that snprintf's result is
        entirely ASCII if the directive contain the glibc 'I' flag.

diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index bd13002e98..8e6596df2f 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -5836,11 +5836,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 
 #if !DCHAR_IS_TCHAR
                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
-                    if (dp->conversion == 'c' || dp->conversion == 's')
+                    if (dp->conversion == 'c' || dp->conversion == 's'
+# if __GLIBC__ >= 2 && !defined __UCLIBC__
+                        || (flags & FLAG_LOCALIZED)
+# endif
+                       )
                       {
-                        /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
-                           TYPE_WIDE_STRING.
-                           The result string is not certainly ASCII.  */
+                        /* The result string is not guaranteed to be ASCII.  */
                         const TCHAR_T *tmpsrc;
                         DCHAR_T *tmpdst;
                         size_t tmpdst_len;






reply via email to

[Prev in Thread] Current Thread [Next in Thread]