aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.c
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames@darkjames.pl>2014-04-22 23:13:40 +0200
committerAnders Broman <a.broman58@gmail.com>2014-04-24 06:02:48 +0000
commit993adc84d5a5be1ec2e69e8ed3db11fb220a4ad6 (patch)
tree0bddd4fe11a3810c0ff9379ca98abd99b0689f20 /epan/tvbuff.c
parent8759da846f64ecd8b6212ea22919659600e2b7d9 (diff)
Fix counting/ checking for leap years in mktime_utc()
When HAVE_TIMEGM is undefined mktime_utc() might output one day shift (+86400s) for (years <= 1967 or years >= 2100) && month >= 3 { .tm_mday = 1 .tm_mon = 2 .tm_year = 67 } mktime_utc() = -89436590 // Thu Mar 2 00:00:00 UTC 1967 gmtime() = -89596800 // Wed Mar 1 00:00:00 UTC 1967 { .tm_mday = 1 .tm_mon = 2 .tm_year = 200 } mktime_utc() = 4107628800 // Tue Mar 2 00:00:00 UTC 2100 gmtime() = 4107542400 // Mon Mar 1 00:00:00 UTC 2100 Change-Id: I1a544762fa5178c8798496d7dc30a2e767919149 Reviewed-on: https://code.wireshark.org/review/1287 Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r--epan/tvbuff.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index 04a8cef71e..005cf46db8 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -1369,6 +1369,8 @@ mktime_utc (struct tm *tm)
{
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
+
+ int yr;
#endif
#ifndef HAVE_TIMEGM
@@ -1376,11 +1378,14 @@ mktime_utc (struct tm *tm)
return (time_t) -1;
retval = (tm->tm_year - 70) * 365;
- retval += (tm->tm_year - 68) / 4;
- retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
- if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
- retval -= 1;
+ /* count number of leap years */
+ yr = tm->tm_year + 1900;
+ if (tm->tm_mon + 1 < 3 && (yr % 4) == 0 && ((yr % 100) != 0 || (yr % 400) == 0))
+ yr--;
+ retval += (((yr / 4) - (yr / 100) + (yr / 400)) - 477); /* 477 = ((1970 / 4) - (1970 / 100) + (1970 / 400)) */
+
+ retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;
#else