bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 1/2] Don't dump core if localtime returns NULL


From: Paul Eggert
Subject: [PATCH v2 1/2] Don't dump core if localtime returns NULL
Date: Fri, 24 Mar 2023 14:08:10 -0700

* 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]