Mercurial > hg > octave-lyh > gnulib-hg
changeset 14247:8d2265e4de51
mktime: systematically normalize tm_isdst comparisons
* lib/mktime.c (isdst_differ): New function.
(__mktime_internal): Use it systematically for all isdst comparisons.
This completes the fix for libc BZ #6723, and removes the need for
normalizing tm_isdst. See
<http://sourceware.org/bugzilla/show_bug.cgi?id=6723>
(not_equal_tm) [DEBUG]: Use isdst_differ here, too.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sat, 29 Jan 2011 23:00:55 -0800 |
parents | f1e2d2684f0b |
children | d10e6185929a |
files | ChangeLog lib/mktime.c |
diffstat | 2 files changed, 20 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2011-01-29 Paul Eggert <eggert@cs.ucla.edu> + mktime: systematically normalize tm_isdst comparisons + * lib/mktime.c (isdst_differ): New function. + (__mktime_internal): Use it systematically for all isdst comparisons. + This completes the fix for libc BZ #6723, and removes the need for + normalizing tm_isdst. See + <http://sourceware.org/bugzilla/show_bug.cgi?id=6723> + (not_equal_tm) [DEBUG]: Use isdst_differ here, too. + mktime: fix some integer overflow issues and sidestep the rest This was prompted by a bug report by Benjamin Lindner for MinGW
--- a/lib/mktime.c +++ b/lib/mktime.c @@ -171,6 +171,14 @@ # include "mktime-internal.h" #endif +/* Return 1 if the values A and B differ according to the rules for + tm_isdst: A and B differ if one is zero and the other positive. */ +static int +isdst_differ (int a, int b) +{ + return (!a != !b) & (0 <= a) & (0 <= b); +} + /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks were not adjusted between the time stamps. @@ -356,9 +364,7 @@ int mday = tp->tm_mday; int mon = tp->tm_mon; int year_requested = tp->tm_year; - /* Normalize the value. */ - int isdst = ((tp->tm_isdst >> (8 * sizeof (tp->tm_isdst) - 1)) - | (tp->tm_isdst != 0)); + int isdst = tp->tm_isdst; /* 1 if the previous probe was DST. */ int dst2; @@ -488,7 +494,7 @@ /* We have a match. Check whether tm.tm_isdst has the requested value, if any. */ - if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst) + if (isdst_differ (isdst, tm.tm_isdst)) { /* tm.tm_isdst has the wrong value. Look for a neighboring time with the right value, and use its UTC offset. @@ -526,7 +532,7 @@ time_t ot = t + delta * direction; struct tm otm; ranged_convert (convert, &ot, &otm); - if (otm.tm_isdst == isdst) + if (! isdst_differ (isdst, otm.tm_isdst)) { /* We found the desired tm_isdst. Extrapolate back to the desired time. */ @@ -602,7 +608,7 @@ | (a->tm_mon ^ b->tm_mon) | (a->tm_year ^ b->tm_year) | (a->tm_yday ^ b->tm_yday) - | (a->tm_isdst ^ b->tm_isdst)); + | isdst_differ (a->tm_isdst, b->tm_isdst)); } static void