* examples/loadables/stat.c (stattime): * examples/loadables/strftime.c (strftime_builtin): * lib/readline/examples/histexamp.c (main): * parse.y (decode_prompt_string): * support/man2html.c (print_sig): Do something reasonable if localtime returns NULL. This can happen, for example, if someone sets the system clock to such an absurdly high value so that tm_year cannot represent the year, and localtime returns NULL with errno == EOVERFLOW. --- examples/loadables/stat.c | 2 ++ examples/loadables/strftime.c | 7 +++++++ lib/readline/examples/histexamp.c | 6 ++++-- parse.y | 35 +++++++++++++++++++++---------- support/man2html.c | 5 ++++- 5 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/examples/loadables/stat.c b/examples/loadables/stat.c index 3ca1a589..3ca2417a 100644 --- a/examples/loadables/stat.c +++ b/examples/loadables/stat.c @@ -261,6 +261,8 @@ stattime (time_t t, const char *timefmt) fmt = timefmt ? timefmt : DEFTIMEFMT; tm = localtime (&t); + if (!tm) + return itos (t); ret = xmalloc (TIMELEN_MAX); diff --git a/examples/loadables/strftime.c b/examples/loadables/strftime.c index e6c8141e..43fb3839 100644 --- a/examples/loadables/strftime.c +++ b/examples/loadables/strftime.c @@ -80,6 +80,13 @@ strftime_builtin (WORD_LIST *list) secs = NOW; t = localtime (&secs); + if (!t) + { + builtin_error ("%s: %s", + list && list->word->word ? list->word->word : "now", + _("timestamp out of range")); + return (EXECUTION_FAILURE); + } tbsize = strlen (format) * 4; tbuf = 0; diff --git a/lib/readline/examples/histexamp.c b/lib/readline/examples/histexamp.c index 309d769b..b321dd0b 100644 --- a/lib/readline/examples/histexamp.c +++ b/lib/readline/examples/histexamp.c @@ -97,9 +97,11 @@ main (argc, argv) if (the_list) for (i = 0; the_list[i]; i++) { + struct tm *tm; tt = history_get_time (the_list[i]); - if (tt) - strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt)); + tm = tt ? localtime (&tt) : 0; + if (tm) + strftime (timestr, sizeof (timestr), "%a %R", tm); else strcpy (timestr, "??"); printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line); diff --git a/parse.y b/parse.y index 639912b6..b758756a 100644 --- a/parse.y +++ b/parse.y @@ -5982,7 +5982,12 @@ decode_prompt_string (char *string) #endif tm = localtime (&the_time); - if (c == 'd') + if (!tm) + { + strcpy (timebuf, "??"); + tslen = 2; + } + else if (c == 'd') tslen = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm); else if (c == 't') tslen = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm); @@ -6008,19 +6013,27 @@ decode_prompt_string (char *string) (void) time (&the_time); tm = localtime (&the_time); string += 2; /* skip { */ - timefmt = xmalloc (strlen (string) + 3); - for (t = timefmt; *string && *string != '}'; ) - *t++ = *string++; - *t = '\0'; + t = string; + while (*string && *string != '}') + string++; c = *string; /* tested at add_string */ - if (timefmt[0] == '\0') + + if (tm) + { + size_t timefmtlen = string - t; + timefmt = xmalloc (timefmtlen + 3); + memcpy (timefmt, t, timefmtlen); + timefmt[timefmtlen] = '\0'; + if (timefmtlen == 0) + strcpy (timefmt, "%X"); /* locale-specific current time */ + tslen = strftime (timebuf, sizeof (timebuf), timefmt, tm); + free (timefmt); + } + else { - timefmt[0] = '%'; - timefmt[1] = 'X'; /* locale-specific current time */ - timefmt[2] = '\0'; + strcpy (timebuf, "??"); + tslen = 2; } - tslen = strftime (timebuf, sizeof (timebuf), timefmt, tm); - free (timefmt); if (tslen == 0) timebuf[0] = '\0'; diff --git a/support/man2html.c b/support/man2html.c index e6f441b4..58165796 100644 --- a/support/man2html.c +++ b/support/man2html.c @@ -455,7 +455,10 @@ print_sig(void) datbuf[0] = '\0'; clock = time(NULL); timetm = localtime(&clock); - strftime(datbuf, MED_STR_MAX, TIMEFORMAT, timetm); + if (timetm) + strftime(datbuf, MED_STR_MAX, TIMEFORMAT, timetm); + else + strcpy(datbuf, "??"); printf(signature, manpage, datbuf); } -- 2.39.2