Skip to content

Commit

Permalink
parse_date_basic(): let the system handle DST conversion
Browse files Browse the repository at this point in the history
The function parses the input to compute the broken-down time in
"struct tm", and the GMT timezone offset.  If the timezone offset
does not exist in the input, the broken-down time is turned into the
number of seconds since epoch both in the current timezone and in
GMT and the offset is computed as their difference.

However, we forgot to make sure tm.tm_isdst is set to -1 (i.e. let
the system figure out if DST is in effect in the current timezone
when turning the broken-down time to the number of seconds since
epoch); it is done so at the beginning of the function, but a call
to match_digit() in the function can lead to a call to gmtime_r() to
clobber the field.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Diagnosed-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Junio C Hamano committed Apr 15, 2015
1 parent 7fcec48 commit f6e6362
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions date.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,13 +694,17 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
date += match;
}

/* mktime uses local timezone */
/* do not use mktime(), which uses local timezone, here */
*timestamp = tm_to_time_t(&tm);
if (*timestamp == -1)
return -1;

if (*offset == -1) {
time_t temp_time = mktime(&tm);
time_t temp_time;

/* gmtime_r() in match_digit() may have clobbered it */
tm.tm_isdst = -1;
temp_time = mktime(&tm);
if ((time_t)*timestamp > temp_time) {
*offset = ((time_t)*timestamp - temp_time) / 60;
} else {
Expand Down

0 comments on commit f6e6362

Please sign in to comment.