diff options
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/printf_fp.c | 17 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 18 |
2 files changed, 21 insertions, 14 deletions
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..434ad86b61 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -747,7 +747,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) { \ int temp = width; \ width = prec; \ - PAD (L_('0'));; \ + PAD (L_('0')); \ width = temp; \ } \ \ @@ -1499,18 +1499,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); |