aboutsummaryrefslogtreecommitdiff
path: root/date.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2014-02-24 02:39:45 -0500
committerJunio C Hamano <gitster@pobox.com>2014-02-24 10:12:58 -0800
commit7ca36d9398a85e7974d04f8fbd2c6adb088290e1 (patch)
treee3ef065ab5fee09448ad78239edefb09c9ca927a /date.c
parentd4b8de0420ffcc7a654ddc6c69a96d3c1b25b4fa (diff)
downloadgit-7ca36d9398a85e7974d04f8fbd2c6adb088290e1.tar.gz
git-7ca36d9398a85e7974d04f8fbd2c6adb088290e1.tar.xz
date: check date overflow against time_t
When we check whether a timestamp has overflowed, we check only against ULONG_MAX, meaning that strtoul has overflowed. However, we also feed these timestamps to system functions like gmtime, which expect a time_t. On many systems, time_t is actually smaller than "unsigned long" (e.g., because it is signed), and we would overflow when using these functions. We don't know the actual size or signedness of time_t, but we can easily check for truncation with a simple assignment. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'date.c')
-rw-r--r--date.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/date.c b/date.c
index 57331ed40..2dae471dd 100644
--- a/date.c
+++ b/date.c
@@ -1085,3 +1085,20 @@ unsigned long approxidate_careful(const char *date, int *error_ret)
gettimeofday(&tv, NULL);
return approxidate_str(date, &tv, error_ret);
}
+
+int date_overflows(unsigned long t)
+{
+ time_t sys;
+
+ /* If we overflowed our unsigned long, that's bad... */
+ if (t == ULONG_MAX)
+ return 1;
+
+ /*
+ * ...but we also are going to feed the result to system
+ * functions that expect time_t, which is often "signed long".
+ * Make sure that we fit into time_t, as well.
+ */
+ sys = t;
+ return t != sys || (t < 1) != (sys < 1);
+}