Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 7ca36d9

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d4b8de0 commit 7ca36d9

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ void datestamp(char *buf, int bufsize);
909909
unsigned long approxidate_careful(const char *, int *);
910910
unsigned long approxidate_relative(const char *date, const struct timeval *now);
911911
enum date_mode parse_date_format(const char *format);
912+
int date_overflows(unsigned long date);
912913

913914
#define IDENT_STRICT 1
914915
#define IDENT_NO_DATE 2

date.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,3 +1085,20 @@ unsigned long approxidate_careful(const char *date, int *error_ret)
10851085
gettimeofday(&tv, NULL);
10861086
return approxidate_str(date, &tv, error_ret);
10871087
}
1088+
1089+
int date_overflows(unsigned long t)
1090+
{
1091+
time_t sys;
1092+
1093+
/* If we overflowed our unsigned long, that's bad... */
1094+
if (t == ULONG_MAX)
1095+
return 1;
1096+
1097+
/*
1098+
* ...but we also are going to feed the result to system
1099+
* functions that expect time_t, which is often "signed long".
1100+
* Make sure that we fit into time_t, as well.
1101+
*/
1102+
sys = t;
1103+
return t != sys || (t < 1) != (sys < 1);
1104+
}

fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
266266
(*ident)++;
267267
if (**ident == '0' && (*ident)[1] != ' ')
268268
return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
269-
if (strtoul(*ident, &end, 10) == ULONG_MAX)
269+
if (date_overflows(strtoul(*ident, &end, 10)))
270270
return error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
271271
if (end == *ident || *end != ' ')
272272
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");

0 commit comments

Comments
 (0)