* 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