1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-05 19:35:52 +03:00

* stdlib/strfmon_l.c (__vstrfmon_l): Don't wrap when computing width.

Numerically stable check for valid width.
This commit is contained in:
Ulrich Drepper
2009-04-18 19:53:59 +00:00
parent 59a7162b17
commit 153aa31b93
2 changed files with 19 additions and 9 deletions

View File

@@ -1,5 +1,8 @@
2009-04-18 Ulrich Drepper <drepper@redhat.com> 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.
* locale/programs/locarchive.c (open_archive): Map the entire file * locale/programs/locarchive.c (open_archive): Map the entire file
and not just the administrative data. and not just the administrative data.
(add_locale): When we find a hash sum match compare the content (add_locale): When we find a hash sum match compare the content

View File

@@ -1,5 +1,5 @@
/* Formatting a monetary value according to the given locale. /* 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. 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; int done;
const char *currency_symbol; const char *currency_symbol;
size_t currency_symbol_len; size_t currency_symbol_len;
int width; long int width;
char *startp; char *startp;
const void *ptr; const void *ptr;
char space_char; char space_char;
@@ -221,13 +221,21 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format,
while (isdigit (*++fmt)) while (isdigit (*++fmt))
{ {
width *= 10; int val = to_digit (*fmt);
width += 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 /* If we don't have enough room for the demanded width we
can stop now and return an error. */ can stop now and return an error. */
if (dest + width >= s + maxsize) if (width >= maxsize - (dest - s))
{ {
__set_errno (E2BIG); __set_errno (E2BIG);
return -1; return -1;
@@ -560,7 +568,7 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format,
out_char (space_char); out_char (space_char);
out_nstring (currency_symbol, currency_symbol_len); out_nstring (currency_symbol, currency_symbol_len);
} }
if (sign_posn == 4) if (sign_posn == 4)
{ {
if (sep_by_space == 2) if (sep_by_space == 2)
@@ -589,9 +597,8 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format,
while (dest - startp < width); while (dest - startp < width);
else else
{ {
int dist = width - (dest - startp); long int dist = width - (dest - startp);
char *cp; for (char *cp = dest - 1; cp >= startp; --cp)
for (cp = dest - 1; cp >= startp; --cp)
cp[dist] = cp[0]; cp[dist] = cp[0];
dest += dist; dest += dist;