# HG changeset patch # User Paul Eggert # Date 1143492005 0 # Node ID e112ec9aa49bb13da7c2de0963b09f29f289eb0b # Parent 9b01abe1321929d5d0de5d2e783e891645593e3d * b2m.c: Include . (TM_YEAR_IN_ASCTIME_RANGE): New macro. (main): Check for out-of-range time stamps. * fakemail.c: Likewise. diff -r 9b01abe13219 -r e112ec9aa49b lib-src/ChangeLog --- a/lib-src/ChangeLog Mon Mar 27 20:33:33 2006 +0000 +++ b/lib-src/ChangeLog Mon Mar 27 20:40:05 2006 +0000 @@ -1,3 +1,10 @@ +2006-03-27 Paul Eggert + + * b2m.c: Include . + (TM_YEAR_IN_ASCTIME_RANGE): New macro. + (main): Check for out-of-range time stamps. + * fakemail.c: Likewise. + 2006-03-18 Andre Spiegel * vcdiff: Use "echo" as a default for $echo, otherwise we'll diff -r 9b01abe13219 -r e112ec9aa49b lib-src/b2m.c --- a/lib-src/b2m.c Mon Mar 27 20:33:33 2006 +0000 +++ b/lib-src/b2m.c Mon Mar 27 20:40:05 2006 +0000 @@ -26,6 +26,7 @@ #undef static #endif +#include #include #include #include @@ -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 @@ { logical labels_saved, printing, header; time_t ltoday; + struct tm *tm; char *labels, *p, *today; struct linebuffer data; @@ -131,7 +144,13 @@ labels_saved = printing = header = FALSE; ltoday = time (0); - today = ctime (<oday); + /* 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 (<oday); + 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); diff -r 9b01abe13219 -r e112ec9aa49b lib-src/fakemail.c --- a/lib-src/fakemail.c Mon Mar 27 20:33:33 2006 +0000 +++ b/lib-src/fakemail.c Mon Mar 27 20:40:05 2006 +0000 @@ -53,6 +53,7 @@ #include "ntlib.h" #endif +#include #include #include #include @@ -70,6 +71,17 @@ #define true 1 #define false 0 +/* 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 + /* Various lists */ struct line_record @@ -354,6 +366,7 @@ { char *the_string, *temp; long idiotic_interface; + struct tm *tm; long prefix_length; long user_length; long date_length; @@ -361,7 +374,13 @@ prefix_length = strlen (FROM_PREFIX); time (&idiotic_interface); - the_date = ctime (&idiotic_interface); + /* 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 (&idiotic_interface); + if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year))) + fatal ("current time is out of range", 0); + the_date = asctime (tm); /* the_date has an unwanted newline at the end */ date_length = strlen (the_date) - 1; the_date[date_length] = '\0';