aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-07-22 07:02:05 +0000
committerUlrich Drepper <drepper@redhat.com>2000-07-22 07:02:05 +0000
commit40c014b3dcc698ae2cc935aefabbeb2196088128 (patch)
treead1ae53dfe308220ec4fc6d32521986d627891c6
parentc056ee48cbf7d3fc88d840af64d75c68ac281519 (diff)
downloadglibc-40c014b3dcc698ae2cc935aefabbeb2196088128.zip
glibc-40c014b3dcc698ae2cc935aefabbeb2196088128.tar.gz
glibc-40c014b3dcc698ae2cc935aefabbeb2196088128.tar.bz2
Update.
2000-07-22 Ulrich Drepper <drepper@redhat.com> * stdio-common/vfprintf.c (process_string_arg): Correct handling of multibyte character strings in %s format with precision.
-rw-r--r--ChangeLog5
-rw-r--r--stdio-common/vfprintf.c31
2 files changed, 33 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ec60f4a..b15e128 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-07-22 Ulrich Drepper <drepper@redhat.com>
+
+ * stdio-common/vfprintf.c (process_string_arg): Correct handling
+ of multibyte character strings in %s format with precision.
+
2000-07-21 Ulrich Drepper <drepper@redhat.com>
* locale/programs/ld-collate.c (collate_read): Allow collating
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 23981d1..1682b0b 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -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); \
} \