From 7678c7757fdf133db5edf17c7b3f6097b76e6ade Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 8 Nov 2018 10:20:50 -0800 Subject: [PATCH 4/7] mktime: make more room for overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [BZ#23789] * time/mktime.c (long_int): Now 4⨯ int, not just 3⨯. This is so that we can add tm_diff results to a previous guess, which will be useful in a later patch. --- ChangeLog | 6 ++++++ time/mktime.c | 20 +++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index b7008a8972..82cdd795ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2018-11-09 Paul Eggert + mktime: make more room for overflow + [BZ#23789] + * time/mktime.c (long_int): Now 4⨯ int, not just 3⨯. + This is so that we can add tm_diff results to a previous guess, + which will be useful in a later patch. + mktime: simplify offset guess [BZ#23789] * time/mktime.c (__mktime_internal): Omit excess precision. diff --git a/time/mktime.c b/time/mktime.c index 0f905eb8fe..ffbb5ea171 100644 --- a/time/mktime.c +++ b/time/mktime.c @@ -120,11 +120,12 @@ my_tzset (void) #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL /* A signed type that can represent an integer number of years - multiplied by three times the number of seconds in a year. It is + multiplied by four times the number of seconds in a year. It is needed when converting a tm_year value times the number of seconds - in a year. The factor of three comes because these products need + in a year. The factor of four comes because these products need to be subtracted from each other, and sometimes with an offset - added to them, without worrying about overflow. + added to them, and then with another timestamp added, without + worrying about overflow. Much of the code uses long_int to represent time_t values, to lessen the hassle of dealing with platforms where time_t is @@ -132,12 +133,12 @@ my_tzset (void) time_t values that mktime can generate even on platforms where time_t is excessively wide. */ -#if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60 +#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 typedef long int long_int; #else typedef long long int long_int; #endif -verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 3 / 366 / 24 / 60 / 60); +verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); /* Shift A right by B bits portably, by dividing A by 2**B and truncating towards minus infinity. B should be in the range 0 <= B @@ -211,9 +212,10 @@ isdst_differ (int a, int b) were not adjusted between the timestamps. The YEAR values uses the same numbering as TP->tm_year. Values - need not be in the usual range. However, YEAR1 must not overflow - when multiplied by three times the number of seconds in a year, and - likewise for YDAY1 and three times the number of seconds in a day. */ + need not be in the usual range. However, YEAR1 - YEAR0 must not + overflow even when multiplied by three times the number of seconds + in a year, and likewise for YDAY1 - YDAY0 and three times the + number of seconds in a day. */ static long_int ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, @@ -403,7 +405,7 @@ __mktime_internal (struct tm *tp, if (LEAP_SECONDS_POSSIBLE) { /* Handle out-of-range seconds specially, - since ydhms_tm_diff assumes every minute has 60 seconds. */ + since ydhms_diff assumes every minute has 60 seconds. */ if (sec < 0) sec = 0; if (59 < sec) -- 2.19.1