Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
glibc
glibc-2.11-strfmon.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File glibc-2.11-strfmon.diff of Package glibc
2009-04-18 Ulrich Drepper <drepper@redhat.com> * stdlib/strfmon_l.c (__vstrfmon_l): Don't wrap when computing width. Numerically stable check for valid width. diff --git a/stdlib/strfmon_l.c b/stdlib/strfmon_l.c index c9f3a47..8e63d45 100644 --- a/stdlib/strfmon_l.c +++ b/stdlib/strfmon_l.c @@ -1,5 +1,5 @@ /* Formatting a monetary value according to the given locale. - Copyright (C) 1996, 1997, 2002, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 1996,1997,2002,2004,2006,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -133,7 +133,7 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, int done; const char *currency_symbol; size_t currency_symbol_len; - int width; + long int width; char *startp; const void *ptr; char space_char; @@ -221,13 +221,21 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, while (isdigit (*++fmt)) { - width *= 10; - width += to_digit (*fmt); + int val = to_digit (*fmt); + + if (width > LONG_MAX / 10 + || (width == LONG_MAX && val > LONG_MAX % 10)) + { + __set_errno (E2BIG); + return -1; + } + + width = width * 10 + val; } /* If we don't have enough room for the demanded width we can stop now and return an error. */ - if (dest + width >= s + maxsize) + if (width >= maxsize - (dest - s)) { __set_errno (E2BIG); return -1; @@ -589,9 +597,8 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, while (dest - startp < width); else { - int dist = width - (dest - startp); - char *cp; - for (cp = dest - 1; cp >= startp; --cp) + long int dist = width - (dest - startp); + for (char *cp = dest - 1; cp >= startp; --cp) cp[dist] = cp[0]; dest += dist; 2009-09-28 Andreas Schwab <schwab@redhat.com> * stdio-common/printf_fp.c: Check for and avoid integer overflows. * stdio-common/vfprintf.c: Likewise. diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index cd3ada6..b60ddec 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -891,8 +891,15 @@ ___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 (chars_needed >= (size_t) -1 / sizeof (wchar_t) - 2 + || chars_needed < fracdig_max, 0)) + { + /* Some overflow occurred. */ + __set_errno (ERANGE); + return -1; + } + size_t wbuffer_to_alloc = (2 + chars_needed) * sizeof (wchar_t); + buffer_malloced = ! __libc_use_alloca (wbuffer_to_alloc); if (__builtin_expect (buffer_malloced, 0)) { wbuffer = (wchar_t *) malloc (wbuffer_to_alloc); diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 38ba8ff..6e0e85c 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -1439,23 +1439,29 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) left = 1; } - if (width + 32 >= (int) (sizeof (work_buffer) - / sizeof (work_buffer[0]))) + if (__builtin_expect (width >= (size_t) -1 / sizeof (CHAR_T) - 32, 0)) + { + __set_errno (ERANGE); + done = -1; + goto all_done; + } + + if (width >= sizeof (work_buffer) / sizeof (work_buffer[0]) - 32) { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) - + (width + 32)); + size_t needed = ((size_t) width + 32) * sizeof (CHAR_T); + if (__libc_use_alloca (needed)) + workend = (CHAR_T *) alloca (needed) + width + 32; else { - workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); + workstart = (CHAR_T *) malloc (needed); if (workstart == NULL) { done = -1; goto all_done; } - workend = workstart + (width + 32); + workend = workstart + width + 32; } } } @@ -1465,22 +1471,29 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) LABEL (width): width = read_int (&f); - if (width + 32 >= (int) (sizeof (work_buffer) / sizeof (work_buffer[0]))) + if (__builtin_expect (width >= (size_t) -1 / sizeof (CHAR_T) - 32, 0)) + { + __set_errno (ERANGE); + done = -1; + goto all_done; + } + + if (width >= sizeof (work_buffer) / sizeof (work_buffer[0]) - 32) { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) - workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) - + (width + 32)); + size_t needed = ((size_t) width + 32) * sizeof (CHAR_T); + if (__libc_use_alloca (needed)) + workend = (CHAR_T *) alloca (needed) + width + 32; else { - workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T)); + workstart = (CHAR_T *) malloc (needed); if (workstart == NULL) { done = -1; goto all_done; } - workend = workstart + (width + 32); + workend = workstart + width + 32; } } if (*f == L_('$')) @@ -1510,18 +1523,18 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else prec = 0; if (prec > width - && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) + && prec > sizeof (work_buffer) / sizeof (work_buffer[0]) - 32) { - if (__builtin_expect (prec > ~((size_t) 0) / sizeof (CHAR_T) - 31, - 0)) + if (__builtin_expect (prec >= (size_t) -1 / sizeof (CHAR_T) - 32, 0)) { + __set_errno (ERANGE); 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)); + workend = (CHAR_T *) alloca (needed) + prec + 32; else { workstart = (CHAR_T *) malloc (needed); @@ -1530,7 +1543,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) done = -1; goto all_done; } - workend = workstart + ((size_t) prec + 32); + workend = workstart + prec + 32; } } JUMP (*f, step2_jumps);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor