X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstrftime.c;h=1adcaa4ba469b63a8232dfc52e095e59c14b50be;hb=a76a349e949dfad5716eb3893052070b770e949f;hp=b9b468a4ab13c8cf76818e61fb6ea295bcce3175;hpb=c6e790b68a07fce728256a505e6ad341b5853952;p=gnulib.git diff --git a/lib/strftime.c b/lib/strftime.c index b9b468a4a..1adcaa4ba 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -265,7 +265,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) \ { \ @@ -292,27 +292,19 @@ static const CHAR_T zeroes[16] = /* "0000000000000000" */ MEMCPY ((PTR) p, (const PTR) (s), _n)) #ifdef COMPILE_WIDE -# ifdef USE_IN_EXTENDED_LOCALE_MODEL -# define widen(os, ws, l) \ +# ifndef USE_IN_EXTENDED_LOCALE_MODEL +# undef __mbsrtowcs_l +# define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st) +# endif +# define widen(os, ws, l) \ { \ mbstate_t __st; \ 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); \ } -# else -# define widen(os, ws, l) \ - { \ - mbstate_t __st; \ - const char *__s = os; \ - memset (&__st, '\0', sizeof (__st)); \ - l = __mbsrtowcs (NULL, &__s, 0, &__st); \ - ws = alloca ((l + 1) * sizeof (wchar_t)); \ - (void) __mbsrtowcs (ws, &__s, l, &__st); \ - } -# endif #endif @@ -488,8 +480,10 @@ static CHAR_T const month_name[][10] = #else # ifdef COMPILE_WIDE # define my_strftime wcsftime +# define nl_get_alt_digit _nl_get_walt_digit # else # define my_strftime strftime +# define nl_get_alt_digit _nl_get_alt_digit # endif # define extra_args # define extra_args_spec @@ -754,8 +748,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)); @@ -779,10 +780,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_('%'): @@ -986,8 +987,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: @@ -998,13 +999,8 @@ my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM) #ifdef _NL_CURRENT /* Get the locale specific alternate representation of the number NUMBER_VALUE. If none exist NULL is returned. */ -# ifdef COMPILE_WIDE - const wchar_t *cp = _nl_get_walt_digit (number_value - HELPER_LOCALE_ARG); -# else - const char *cp = _nl_get_alt_digit (number_value - HELPER_LOCALE_ARG); -# endif + const CHAR_T *cp = nl_get_alt_digit (number_value + HELPER_LOCALE_ARG); if (cp != NULL) { @@ -1044,18 +1040,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; + } } }