diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | stdio-common/tst-sprintf.c | 21 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 11 |
3 files changed, 37 insertions, 4 deletions
@@ -1,3 +1,12 @@ +2007-05-21 Jakub Jelinek <jakub@redhat.com> + + [BZ #4514] + * stdio-common/vfprintf.c (vfprintf): Don't shadow workstart variable, + reinitialize workend at the start of each do_positional format spec + loop, free workstart before do_positional loops. + (printf_unknown): Fix size of work_buffer. + * stdio-common/tst-sprintf.c (main): Add 3 new testcases. + 2007-05-10 Ulrich Drepper <drepper@redhat.com> * include/sys/cdefs.h: Redefine __nonnull so that test for diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c index c61d3b50e4..c04fef18f4 100644 --- a/stdio-common/tst-sprintf.c +++ b/stdio-common/tst-sprintf.c @@ -37,5 +37,26 @@ main (void) free (dst); } + if (sprintf (buf, "%1$d%3$.*2$s%4$d", 7, 67108863, "x", 8) != 3 + || strcmp (buf, "7x8") != 0) + { + printf ("sprintf (buf, \"%%1$d%%3$.*2$s%%4$d\", 7, 67108863, \"x\", 8) produced `%s' output", buf); + result = 1; + } + + if (sprintf (buf, "%67108863.16\"%d", 7) != 14 + || strcmp (buf, "%67108863.16\"7") != 0) + { + printf ("sprintf (buf, \"%%67108863.16\\\"%%d\", 7) produced `%s' output", buf); + result = 1; + } + + if (sprintf (buf, "%*\"%d", 0x3ffffff, 7) != 11 + || strcmp (buf, "%67108863\"7") != 0) + { + printf ("sprintf (buf, \"%%*\\\"%%d\", 0x3ffffff, 7) produced `%s' output", buf); + result = 1; + } + return result; } diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 1377e3c17e..9c9e9a5d9d 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -1626,6 +1626,8 @@ do_positional: /* Just a counter. */ size_t cnt; + free (workstart); + workstart = NULL; if (grouping == (const char *) -1) { @@ -1800,7 +1802,9 @@ do_positional: int use_outdigits = specs[nspecs_done].info.i18n; char pad = specs[nspecs_done].info.pad; CHAR_T spec = specs[nspecs_done].info.spec; - CHAR_T *workstart = NULL; + + workstart = NULL; + workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; /* Fill in last information. */ if (specs[nspecs_done].width_arg != -1) @@ -1896,8 +1900,7 @@ do_positional: break; } - if (__builtin_expect (workstart != NULL, 0)) - free (workstart); + free (workstart); workstart = NULL; /* Write the following constant string. */ @@ -1925,7 +1928,7 @@ printf_unknown (FILE *s, const struct printf_info *info, { int done = 0; - CHAR_T work_buffer[MAX (info->width, info->spec) + 32]; + CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3]; CHAR_T *const workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; register CHAR_T *w; |