summaryrefslogtreecommitdiff
path: root/lib-src/b2m.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src/b2m.c')
-rw-r--r--lib-src/b2m.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib-src/b2m.c b/lib-src/b2m.c
index 5bebe560e2a..adaa736bcd9 100644
--- a/lib-src/b2m.c
+++ b/lib-src/b2m.c
@@ -26,6 +26,7 @@
#undef static
#endif
+#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
@@ -44,6 +45,17 @@
typedef int logical;
+/* True if TM_YEAR is a struct tm's tm_year value that is acceptable
+ to asctime. Glibc asctime returns a useful string unless TM_YEAR
+ is nearly INT_MAX, but the C Standard lets C libraries overrun a
+ buffer if TM_YEAR needs more than 4 bytes. */
+#ifdef __GLIBC__
+# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) ((tm_year) <= INT_MAX - 1900)
+#else
+# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \
+ (-999 - 1900 <= (tm_year) && (tm_year) <= 9999 - 1900)
+#endif
+
/*
* A `struct linebuffer' is a structure which holds a line of text.
* `readline' reads a line from a stream into a linebuffer and works
@@ -87,6 +99,7 @@ main (argc, argv)
{
logical labels_saved, printing, header;
time_t ltoday;
+ struct tm *tm;
char *labels, *p, *today;
struct linebuffer data;
@@ -131,7 +144,13 @@ main (argc, argv)
labels_saved = printing = header = FALSE;
ltoday = time (0);
- today = ctime (&ltoday);
+ /* Convert to a string, checking for out-of-range time stamps.
+ Don't use 'ctime', as that might dump core if the hardware clock
+ is set to a bizarre value. */
+ tm = localtime (&ltoday);
+ if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year)))
+ fatal ("current time is out of range");
+ today = asctime (tm);
data.size = 200;
data.buffer = xnew (200, char);