aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2018-11-15 22:59:33 +0100
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-11-15 22:59:33 +0100
commitefbdddc381cfea5bfa9527e86fa3078257e5d91b (patch)
treec662e5e2b90e040f93ebc761f3ac25a89335825f
parent6c90d759f613761de7ac435bbabcc373092cf8bc (diff)
downloadglibc-efbdddc381cfea5bfa9527e86fa3078257e5d91b.tar
glibc-efbdddc381cfea5bfa9527e86fa3078257e5d91b.tar.gz
glibc-efbdddc381cfea5bfa9527e86fa3078257e5d91b.tar.bz2
glibc-efbdddc381cfea5bfa9527e86fa3078257e5d91b.zip
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.
-rw-r--r--ChangeLog6
-rw-r--r--time/mktime.c20
2 files changed, 17 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f70c3be7a1..064d0a305c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2018-11-15 Paul Eggert <eggert@cs.ucla.edu>
+ 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)