X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstrftime.c;h=b15dfa9a451053e9ae576f1a45ace92b6fa9bf22;hb=c1ebd28b04d9ecf3abc3fe980eaaac13456ba51e;hp=9a421df44bbdb1be8ed75f3ae874930952f11e13;hpb=7535c9422de3d94d22a3f0dabbeff9623131417d;p=gnulib.git diff --git a/lib/strftime.c b/lib/strftime.c index 9a421df44..b15dfa9a4 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -3,20 +3,19 @@ NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include @@ -265,7 +264,7 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */ int _n = (n); \ int _delta = width - _n; \ int _incr = _n + (_delta > 0 ? _delta : 0); \ - if (i + _incr >= maxsize) \ + if ((size_t) _incr >= maxsize - i) \ return 0; \ if (p) \ { \ @@ -302,7 +301,7 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */ const char *__s = os; \ memset (&__st, '\0', sizeof (__st)); \ l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \ - ws = alloca ((l + 1) * sizeof (wchar_t)); \ + ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \ (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \ } #endif @@ -748,8 +747,15 @@ my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM) width = 0; do { - width *= 10; - width += *f - L_('0'); + if (width > INT_MAX / 10 + || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10)) + /* Avoid overflow. */ + width = INT_MAX; + else + { + width *= 10; + width += *f - L_('0'); + } ++f; } while (ISDIGIT (*f)); @@ -773,10 +779,10 @@ my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM) switch (format_char) { #define DO_NUMBER(d, v) \ - digits = width == -1 ? d : width; \ + digits = d > width ? d : width; \ number_value = v; goto do_number #define DO_NUMBER_SPACEPAD(d, v) \ - digits = width == -1 ? d : width; \ + digits = d > width ? d : width; \ number_value = v; goto do_number_spacepad case L_('%'): @@ -980,8 +986,8 @@ my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM) jump to one of these two labels. */ do_number_spacepad: - /* Force `_' flag unless overwritten by `0' flag. */ - if (pad != L_('0')) + /* Force `_' flag unless overridden by `0' or `-' flag. */ + if (pad != L_('0') && pad != L_('-')) pad = L_('_'); do_number: @@ -1033,18 +1039,37 @@ my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM) int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0])) - bufp); - if (pad == L_('_')) - { - while (0 < padding--) - *--bufp = L_(' '); - } - else + if (padding > 0) { - bufp += negative_number; - while (0 < padding--) - *--bufp = L_('0'); - if (negative_number) - *--bufp = L_('-'); + if (pad == L_('_')) + { + if ((size_t) padding >= maxsize - i) + return 0; + + if (p) + memset_space (p, padding); + i += padding; + width = width > padding ? width - padding : 0; + } + else + { + if ((size_t) digits >= maxsize - i) + return 0; + + if (negative_number) + { + ++bufp; + + if (p) + *p++ = L_('-'); + ++i; + } + + if (p) + memset_zero (p, padding); + i += padding; + width = 0; + } } }