* examples/loadables/stat.c (stattime): * examples/loadables/strftime.c (strftime_builtin): * lib/readline/examples/histexamp.c (main): * parse.y (decode_prompt_string): 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 | 40 ++++++++++++++++++++++--------- 4 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/examples/loadables/stat.c b/examples/loadables/stat.c index 1e60e7b6..cc722c05 100644 --- a/examples/loadables/stat.c +++ b/examples/loadables/stat.c @@ -271,6 +271,8 @@ stattime (t, 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 f4e194e6..656ecdeb 100644 --- a/examples/loadables/strftime.c +++ b/examples/loadables/strftime.c @@ -81,6 +81,13 @@ strftime_builtin (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 1d12e639..1d188101 100644 --- a/parse.y +++ b/parse.y @@ -5775,7 +5775,12 @@ decode_prompt_string (string) #endif tm = localtime (&the_time); - if (c == 'd') + if (!tm) + { + strcpy (timebuf, "??"); + n = 2; + } + else if (c == 'd') n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm); else if (c == 't') n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm); @@ -5801,19 +5806,32 @@ decode_prompt_string (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 (timefmt[0] == '\0') + { + timefmt[0] = '%'; + timefmt[1] = 'X'; /* locale-specific current time */ + timefmt[2] = '\0'; + } + n = strftime (timebuf, sizeof (timebuf), timefmt, tm); + free (timefmt); + } + else { - timefmt[0] = '%'; - timefmt[1] = 'X'; /* locale-specific current time */ - timefmt[2] = '\0'; + strcpy (timebuf, "??"); + n = 2; } - n = strftime (timebuf, sizeof (timebuf), timefmt, tm); - free (timefmt); if (n == 0) timebuf[0] = '\0'; -- 2.39.2