bug-bash
[Top][All Lists]
Advanced

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

[PATCH] Don't dump core if localtime returns NULL


From: Paul Eggert
Subject: [PATCH] Don't dump core if localtime returns NULL
Date: Wed, 22 Mar 2023 20:23:10 -0700

* 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




reply via email to

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