| 1 | diff --git a/time/strftime_l.c b/time/strftime_l.c |
| 2 | index b48ef34..4eb647c 100644 |
| 3 | --- a/time/strftime_l.c |
| 4 | +++ b/time/strftime_l.c |
| 5 | @@ -510,13 +510,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument |
| 6 | only a few elements. Dereference the pointers only if the format |
| 7 | requires this. Then it is ok to fail if the pointers are invalid. */ |
| 8 | # define a_wkday \ |
| 9 | - ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) |
| 10 | + ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ |
| 11 | + ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) |
| 12 | # define f_wkday \ |
| 13 | - ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) |
| 14 | + ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ |
| 15 | + ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) |
| 16 | # define a_month \ |
| 17 | - ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) |
| 18 | + ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ |
| 19 | + ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) |
| 20 | # define f_month \ |
| 21 | - ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) |
| 22 | + ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ |
| 23 | + ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) |
| 24 | # define ampm \ |
| 25 | ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ |
| 26 | ? NLW(PM_STR) : NLW(AM_STR))) |
| 27 | @@ -526,8 +530,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument |
| 28 | # define ap_len STRLEN (ampm) |
| 29 | #else |
| 30 | # if !HAVE_STRFTIME |
| 31 | -# define f_wkday (weekday_name[tp->tm_wday]) |
| 32 | -# define f_month (month_name[tp->tm_mon]) |
| 33 | +# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \ |
| 34 | + ? "?" : weekday_name[tp->tm_wday]) |
| 35 | +# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \ |
| 36 | + ? "?" : month_name[tp->tm_mon]) |
| 37 | # define a_wkday f_wkday |
| 38 | # define a_month f_month |
| 39 | # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) |
| 40 | @@ -1321,7 +1327,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument |
| 41 | *tzset_called = true; |
| 42 | } |
| 43 | # endif |
| 44 | - zone = tzname[tp->tm_isdst]; |
| 45 | + zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?"; |
| 46 | } |
| 47 | #endif |
| 48 | if (! zone) |
| 49 | diff --git a/time/tst-strftime.c b/time/tst-strftime.c |
| 50 | index 374fba4..af3ff72 100644 |
| 51 | --- a/time/tst-strftime.c |
| 52 | +++ b/time/tst-strftime.c |
| 53 | @@ -4,6 +4,56 @@ |
| 54 | #include <time.h> |
| 55 | |
| 56 | |
| 57 | +static int |
| 58 | +do_bz18985 (void) |
| 59 | +{ |
| 60 | + char buf[1000]; |
| 61 | + struct tm ttm; |
| 62 | + int rc, ret = 0; |
| 63 | + |
| 64 | + memset (&ttm, 1, sizeof (ttm)); |
| 65 | + ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ |
| 66 | + rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); |
| 67 | + |
| 68 | + if (rc == 66) |
| 69 | + { |
| 70 | + const char expected[] |
| 71 | + = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?"; |
| 72 | + if (0 != strcmp (buf, expected)) |
| 73 | + { |
| 74 | + printf ("expected:\n %s\ngot:\n %s\n", expected, buf); |
| 75 | + ret += 1; |
| 76 | + } |
| 77 | + } |
| 78 | + else |
| 79 | + { |
| 80 | + printf ("expected 66, got %d\n", rc); |
| 81 | + ret += 1; |
| 82 | + } |
| 83 | + |
| 84 | + /* Check negative values as well. */ |
| 85 | + memset (&ttm, 0xFF, sizeof (ttm)); |
| 86 | + ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ |
| 87 | + rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); |
| 88 | + |
| 89 | + if (rc == 30) |
| 90 | + { |
| 91 | + const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 "; |
| 92 | + if (0 != strcmp (buf, expected)) |
| 93 | + { |
| 94 | + printf ("expected:\n %s\ngot:\n %s\n", expected, buf); |
| 95 | + ret += 1; |
| 96 | + } |
| 97 | + } |
| 98 | + else |
| 99 | + { |
| 100 | + printf ("expected 30, got %d\n", rc); |
| 101 | + ret += 1; |
| 102 | + } |
| 103 | + |
| 104 | + return ret; |
| 105 | +} |
| 106 | + |
| 107 | static struct |
| 108 | { |
| 109 | const char *fmt; |
| 110 | @@ -104,7 +154,7 @@ do_test (void) |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | - return result; |
| 115 | + return result + do_bz18985 (); |
| 116 | } |
| 117 | |
| 118 | #define TEST_FUNCTION do_test () |
| 119 | -- |
| 120 | 1.9.4 |
| 121 | |