(process_string_arg): Correct handling of multibyte character strings
authordrepper <drepper>
Sat, 22 Jul 2000 07:01:03 +0000 (07:01 +0000)
committerdrepper <drepper>
Sat, 22 Jul 2000 07:01:03 +0000 (07:01 +0000)
in %s format with precision.

stdio-common/vfprintf.c

index 23981d1..1682b0b 100644 (file)
@@ -1142,9 +1142,34 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
        else if (!is_long && spec != L_('S'))                                 \
          {                                                                   \
            if (prec != -1)                                                   \
-             /* Search for the end of the string, but don't search past      \
-                the length specified by the precision.  */                   \
-             len = __strnlen (string, prec);                                 \
+             {                                                               \
+               /* Search for the end of the string, but don't search past    \
+                  the length (in bytes) specified by the precision.  Also    \
+                  don't use incomplete characters.  */                       \
+               if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1)   \
+                 len = __strnlen (string, prec);                             \
+               else                                                          \
+                 {                                                           \
+                   /* In case we have a multibyte character set the          \
+                      situation is more compilcated.  We must not copy       \
+                      bytes at the end which form an incomplete character. */\
+                   wchar_t ignore[prec];                                     \
+                   const char *str2 = string;                                \
+                   mbstate_t ps;                                             \
+                                                                             \
+                   memset (&ps, '\0', sizeof (ps));                          \
+                   if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps)         \
+                       == (size_t) -1)                                       \
+                     {                                                       \
+                       done = -1;                                            \
+                       goto all_done;                                        \
+                     }                                                       \
+                   if (str2 == NULL)                                         \
+                     len = strlen (string);                                  \
+                   else                                                      \
+                     len = str2 - string - (ps.__count);                     \
+                 }                                                           \
+             }                                                               \
            else                                                              \
              len = strlen (string);                                          \
          }                                                                   \