diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | stdio-common/Makefile | 3 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 31 |
3 files changed, 40 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 9d8c1155b5..11dcb3e071 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2000-09-05 Ulrich Drepper <drepper@redhat.com> + + * stdio-common/vfprintf.c (process_string_arg): Handle precision + in wide char case correctly. Don't allocate too long temporary + strings with alloca. + + * stdio-common/Makefile (tests): Add tst-swprintf. + (tst-swprintf-ENV): New variable. + * stdio-common/tst-swprintf.c: New file. + 2000-09-05 Andreas Jaeger <aj@suse.de> * sysdeps/unix/sysv/linux/mips/bits/stat.h: Use st_pad5. @@ -35,8 +45,8 @@ * soft-fp/sysdeps/sparc/sparc64/Makefile: Move from here... * sysdeps/sparc/sparc64/soft-fp/Makefile: ... to here. - * soft-fp/sysdeps/sparc/sparc64/qp_neg.S: Move from here... - * sysdeps/sparc/sparc64/soft-fp/qp_neg.S: ... to here. + * soft-fp/sysdeps/sparc/sparc64/qp_neg.S: Move from here... + * sysdeps/sparc/sparc64/soft-fp/qp_neg.S: ... to here. * soft-fp/sysdeps/powerpc/q_add.c: Move from here... * sysdeps/powerpc/soft-fp/q_add.c: ... to here. diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 33907ebb60..7e78d44f97 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -54,7 +54,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \ tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ - scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf + scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf tst-swprintf test-srcs = tst-unbputc tst-printf @@ -81,6 +81,7 @@ CFLAGS-scanf7.c = -Wno-format CFLAGS-tst-printfsz.c = -Wno-format tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata +tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata $(inst_includedir)/bits/stdio_lim.h: $(common-objpfx)bits/stdio_lim.h $(do-install) diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index b90f26f7fa..6219d795f8 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -995,6 +995,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) LABEL (form_string): \ { \ size_t len; \ + int string_malloced; \ \ /* The string argument could in fact be `char *' or `wchar_t *'. \ But this should not make a difference here. */ \ @@ -1006,6 +1007,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) /* Entry point for printing other strings. */ \ LABEL (print_string): \ \ + string_malloced = 0; \ if (string == NULL) \ { \ /* Write "(null)" if there's space. */ \ @@ -1028,14 +1030,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) const char *mbs = (const char *) string; \ mbstate_t mbstate; \ \ - len = prec != -1 ? strnlen (mbs, prec) : strlen (mbs); \ + len = prec != -1 ? prec : strlen (mbs); \ \ /* Allocate dynamically an array which definitely is long \ enough for the wide character version. */ \ - string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ + if (len < 8192 \ + || ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ + == NULL)) \ + string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ + else \ + string_malloced = 1; \ \ memset (&mbstate, '\0', sizeof (mbstate_t)); \ - len = __mbsnrtowcs (string, &mbs, len, len, &mbstate); \ + len = __mbsrtowcs (string, &mbs, len, &mbstate); \ if (len == (size_t) -1) \ { \ /* Illegal multibyte character. */ \ @@ -1064,6 +1071,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) outstring (string, len); \ if (left) \ PAD (L' '); \ + if (string_malloced) \ + free (string); \ } \ break; #else @@ -1112,6 +1121,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) LABEL (form_string): \ { \ size_t len; \ + int string_malloced; \ \ /* The string argument could in fact be `char *' or `wchar_t *'. \ But this should not make a difference here. */ \ @@ -1123,6 +1133,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) /* Entry point for printing other strings. */ \ LABEL (print_string): \ \ + string_malloced = 0; \ if (string == NULL) \ { \ /* Write "(null)" if there's space. */ \ @@ -1181,7 +1192,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (prec > 0) \ { \ /* The string `s2' might not be NUL terminated. */ \ - string = (char *) alloca (prec); \ + if (prec < 32768 \ + || (string = (char *) malloc (prec)) == NULL) \ + string = (char *) alloca (prec); \ + else \ + string_malloced = 1; \ len = __wcsrtombs (string, &s2, prec, &mbstate); \ } \ else \ @@ -1191,7 +1206,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ assert (__mbsinit (&mbstate)); \ s2 = (const wchar_t *) string; \ - string = (char *) alloca (len + 1); \ + if (len + 1 < 32768 \ + || (string = (char *) malloc (len + 1)) == NULL) \ + string = (char *) alloca (len + 1); \ + else \ + string_malloced = 1; \ (void) __wcsrtombs (string, &s2, len + 1, &mbstate); \ } \ } \ @@ -1215,6 +1234,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) outstring (string, len); \ if (left) \ PAD (' '); \ + if (string_malloced) \ + free (string); \ } \ break; #endif |