diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-12-12 18:13:35 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-12-12 18:13:35 +0000 |
commit | 574e283890a6ca92325a06dafa76ff307a8019a2 (patch) | |
tree | 055e44e24a55fb4863e5d9cdc04e320cde52ffe9 /stdio-common | |
parent | a162e5955f7e324be82d9318bbcbe869c66ffb86 (diff) |
Updated to fedora-glibc-20071212T1051
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/Makefile | 2 | ||||
-rw-r--r-- | stdio-common/bug20.c | 32 | ||||
-rw-r--r-- | stdio-common/bug21.c | 16 | ||||
-rw-r--r-- | stdio-common/bug22.c | 32 | ||||
-rw-r--r-- | stdio-common/printf_fp.c | 17 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 50 | ||||
-rw-r--r-- | stdio-common/vfscanf.c | 19 |
7 files changed, 135 insertions, 33 deletions
diff --git a/stdio-common/Makefile b/stdio-common/Makefile index f87ac560aa..f9fc9da306 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -57,7 +57,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \ tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ - bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 + bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 test-srcs = tst-unbputc tst-printf diff --git a/stdio-common/bug20.c b/stdio-common/bug20.c new file mode 100644 index 0000000000..385f6ffbe1 --- /dev/null +++ b/stdio-common/bug20.c @@ -0,0 +1,32 @@ +/* BZ #5225 */ +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +static int +do_test (void) +{ + wchar_t in[] = L"123,abc,321"; + /* This is the critical part for this test. format must be in + read-only memory. */ + static const wchar_t format[50] = L"%d,%[^,],%d"; + int out_d1, out_d2; + char out_s[50]; + printf ("in='%ls' format='%ls'\n", in, format); + if (swscanf (in, format, &out_d1, out_s, &out_d2) != 3) + { + puts ("swscanf did not return 3"); + return 1; + } + printf ("in='%ls' format='%ls'\n", in, format); + printf ("out_d1=%d out_s='%s' out_d2=%d\n", out_d1, out_s, out_d2); + if (out_d1 != 123 || strcmp (out_s, "abc") != 0 || out_d2 != 321) + { + puts ("swscanf did not return the correct values"); + return 1; + } + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdio-common/bug21.c b/stdio-common/bug21.c new file mode 100644 index 0000000000..d22b9c1a97 --- /dev/null +++ b/stdio-common/bug21.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +static int +do_test (void) +{ + static const char buf[] = " "; + char *str; + + int r = sscanf (buf, "%as", &str); + printf ("%d %p\n", r, str); + + return r != -1 || str != NULL; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdio-common/bug22.c b/stdio-common/bug22.c new file mode 100644 index 0000000000..2228388b47 --- /dev/null +++ b/stdio-common/bug22.c @@ -0,0 +1,32 @@ +/* BZ #5424 */ +#include <stdio.h> + +#define N 2147483648 + +#define STRINGIFY(S) #S +#define MAKE_STR(S) STRINGIFY(S) + +#define SN MAKE_STR(N) + +static int +do_test (void) +{ + int ret; + + FILE *fp = fopen ("/dev/null", "w"); + if (fp == NULL) + { + puts ("cannot open /dev/null"); + return 1; + } + + ret = fprintf (fp, "%" SN "d%" SN "d", 1, 1); + + printf ("ret = %d\n", ret); + + return ret != -1; +} + +#define TIMEOUT 30 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index ae25ab6fc5..c65cfa9faa 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -808,7 +808,7 @@ ___printf_fp (FILE *fp, { int width = info->width; wchar_t *wstartp, *wcp; - int chars_needed; + size_t chars_needed; int expscale; int intdig_max, intdig_no = 0; int fracdig_min; @@ -823,7 +823,7 @@ ___printf_fp (FILE *fp, type = info->spec; intdig_max = 1; fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec; - chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4; + chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4; /* d . ddd e +- ddd */ dig_max = INT_MAX; /* Unlimited. */ significant = 1; /* Does not matter here. */ @@ -838,12 +838,12 @@ ___printf_fp (FILE *fp, { intdig_max = exponent + 1; /* This can be really big! */ /* XXX Maybe malloc if too big? */ - chars_needed = exponent + 1 + 1 + fracdig_max; + chars_needed = (size_t) exponent + 1 + 1 + (size_t) fracdig_max; } else { intdig_max = 1; - chars_needed = 1 + 1 + fracdig_max; + chars_needed = 1 + 1 + (size_t) fracdig_max; } } else @@ -858,7 +858,7 @@ ___printf_fp (FILE *fp, type = isupper (info->spec) ? 'E' : 'e'; fracdig_max = dig_max - 1; intdig_max = 1; - chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4; + chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4; } else { @@ -870,7 +870,7 @@ ___printf_fp (FILE *fp, zeros can be as many as would be required for exponential notation with a negative two-digit exponent, which is 4. */ - chars_needed = dig_max + 1 + 4; + chars_needed = (size_t) dig_max + 1 + 4; } fracdig_min = info->alt ? fracdig_max : 0; significant = 0; /* We count significant digits. */ @@ -888,16 +888,17 @@ ___printf_fp (FILE *fp, it is possible that we need two more characters in front of all the other output. If the amount of memory we have to allocate is too large use `malloc' instead of `alloca'. */ + size_t wbuffer_to_alloc = (2 + (size_t) chars_needed) * sizeof (wchar_t); buffer_malloced = ! __libc_use_alloca (chars_needed * 2 * sizeof (wchar_t)); if (__builtin_expect (buffer_malloced, 0)) { - wbuffer = (wchar_t *) malloc ((2 + chars_needed) * sizeof (wchar_t)); + wbuffer = (wchar_t *) malloc (wbuffer_to_alloc); if (wbuffer == NULL) /* Signal an error to the caller. */ return -1; } else - wbuffer = (wchar_t *) alloca ((2 + chars_needed) * sizeof (wchar_t)); + wbuffer = (wchar_t *) alloca (wbuffer_to_alloc); wcp = wstartp = wbuffer + 2; /* Let room for rounding. */ /* Do the real work: put digits in allocated buffer. */ diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index d1dc1aaf59..d10a5c6a13 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -64,6 +64,19 @@ } while (0) #define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED) +#define done_add(val) \ + do { \ + unsigned int _val = val; \ + assert ((unsigned int) done < (unsigned int) INT_MAX); \ + if (__builtin_expect ((unsigned int) INT_MAX - (unsigned int) done \ + < _val, 0)) \ + { \ + done = -1; \ + goto all_done; \ + } \ + done += _val; \ + } while (0) + #ifndef COMPILE_WPRINTF # define vfprintf _IO_vfprintf_internal # define CHAR_T char @@ -76,7 +89,7 @@ # define PUT(F, S, N) _IO_sputn ((F), (S), (N)) # define PAD(Padchar) \ if (width > 0) \ - done += INTUSE(_IO_padn) (s, (Padchar), width) + done_add (INTUSE(_IO_padn) (s, (Padchar), width)) # define PUTC(C, F) _IO_putc_unlocked (C, F) # define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\ return -1 @@ -95,7 +108,7 @@ # define PUT(F, S, N) _IO_sputn ((F), (S), (N)) # define PAD(Padchar) \ if (width > 0) \ - done += _IO_wpadn (s, (Padchar), width) + done_add (_IO_wpadn (s, (Padchar), width)) # define PUTC(C, F) _IO_putwc_unlocked (C, F) # define ORIENT if (_IO_fwide (s, 1) != 1) return -1 @@ -116,20 +129,21 @@ do \ { \ register const INT_T outc = (Ch); \ - if (PUTC (outc, s) == EOF) \ + if (PUTC (outc, s) == EOF || done == INT_MAX) \ { \ done = -1; \ goto all_done; \ } \ - else \ - ++done; \ + ++done; \ } \ while (0) #define outstring(String, Len) \ do \ { \ - if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len)) \ + assert ((size_t) done <= (size_t) INT_MAX); \ + if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len) \ + || (size_t) INT_MAX - (size_t) done < (size_t) (Len)) \ { \ done = -1; \ goto all_done; \ @@ -747,7 +761,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ int temp = width; \ width = prec; \ - PAD (L_('0'));; \ + PAD (L_('0')); \ width = temp; \ } \ \ @@ -811,7 +825,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) goto all_done; \ } \ \ - done += function_done; \ + done_add (function_done); \ } \ break; \ \ @@ -865,7 +879,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) goto all_done; \ } \ \ - done += function_done; \ + done_add (function_done); \ } \ break; \ \ @@ -1499,18 +1513,24 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) if (prec > width && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) { - if (__libc_use_alloca ((prec + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((prec + 32) * sizeof (CHAR_T))) - + (prec + 32); + if (__builtin_expect (prec > ~((size_t) 0) - 31, 0)) + { + done = -1; + goto all_done; + } + size_t needed = ((size_t) prec + 32) * sizeof (CHAR_T); + + if (__libc_use_alloca (needed)) + workend = (((CHAR_T *) alloca (needed)) + ((size_t) prec + 32)); else { - workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T)); + workstart = (CHAR_T *) malloc (needed); if (workstart == NULL) { done = -1; goto all_done; } - workend = workstart + (prec + 32); + workend = workstart + ((size_t) prec + 32); } } JUMP (*f, step2_jumps); @@ -1887,7 +1907,7 @@ do_positional: goto all_done; } - done += function_done; + done_add (function_done); } break; } diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index e4728d00c9..a03e19c4e3 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -272,7 +272,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, { \ CHAR_T *old = wp; \ wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \ - wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \ + wp = (CHAR_T *) alloca (wpmax * sizeof (CHAR_T)); \ if (old != NULL) \ MEMCPY (wp, old, wpsize); \ } \ @@ -2314,7 +2314,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (__builtin_expect (fc == L'\0', 0)) conv_error (); - wp = (wchar_t *) f - 1; + wchar_t *twend = (wchar_t *) f - 1; #else /* Fill WP with byte flags indexed by character. We will use this flag map for matching input characters. */ @@ -2365,9 +2365,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, /* Test whether it's in the scanlist. */ runp = tw; - while (runp < wp) + while (runp < twend) { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp + if (runp[0] == L'-' && runp[1] != '\0' + && runp + 1 != twend && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -2405,7 +2406,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, } } - if (runp == wp && !not_in) + if (runp == twend && !not_in) { ungetc (c, s); goto out; @@ -2590,9 +2591,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, /* Test whether it's in the scanlist. */ runp = tw; - while (runp < wp) + while (runp < twend) { - if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp + if (runp[0] == L'-' && runp[1] != '\0' + && runp + 1 != twend && runp != tw && (unsigned int) runp[-1] <= (unsigned int) runp[1]) { @@ -2630,7 +2632,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, } } - if (runp == wp && !not_in) + if (runp == twend && !not_in) { ungetc (c, s); goto out2; @@ -2843,7 +2845,6 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, *p->ptrs[cnt] = NULL; } p = p->next; - free (ptrs_to_free); ptrs_to_free = p; } } |