OSDN Git Service

date.c: abort if the system time cannot handle one of our timestamps
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 26 Apr 2017 19:29:36 +0000 (21:29 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 27 Apr 2017 04:07:40 +0000 (13:07 +0900)
We are about to switch to a new data type for time stamps that is
definitely not smaller or equal, but larger or equal to time_t.

So before using the system functions to process or format timestamps,
let's make extra certain that they can handle what we feed them.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
date.c

diff --git a/date.c b/date.c
index 92ab31a..63fa996 100644 (file)
--- a/date.c
+++ b/date.c
@@ -46,7 +46,17 @@ static time_t gm_time_t(timestamp_t time, int tz)
        minutes = tz < 0 ? -tz : tz;
        minutes = (minutes / 100)*60 + (minutes % 100);
        minutes = tz < 0 ? -minutes : minutes;
-       return time + minutes * 60;
+
+       if (minutes > 0) {
+               if (unsigned_add_overflows(time, minutes * 60))
+                       die("Timestamp+tz too large: %"PRItime" +%04d",
+                           time, tz);
+       } else if (time < -minutes * 60)
+               die("Timestamp before Unix epoch: %"PRItime" %04d", time, tz);
+       time += minutes * 60;
+       if (date_overflows(time))
+               die("Timestamp too large for this system: %"PRItime, time);
+       return (time_t)time;
 }
 
 /*
@@ -70,7 +80,10 @@ static int local_tzoffset(timestamp_t time)
        struct tm tm;
        int offset, eastwest;
 
-       t = time;
+       if (date_overflows(time))
+               die("Timestamp too large for this system: %"PRItime, time);
+
+       t = (time_t)time;
        localtime_r(&t, &tm);
        t_local = tm_to_time_t(&tm);