zic -s bug fixes for year/time extremes (found by code inspection)
Paul Eggert
eggert at twinsun.com
Mon Mar 3 04:13:06 UTC 1997
I briefly looked for a fix for the problem that Dave Sparks reported
today with zic.c, and decided that this will require more zic
expertise than I have. However, I did find a couple of related bugs
in zic.c by code inspection.
First, there are a couple of places in the code that compare for
equality to min_year, but values less than min_year are possible if -s
is given, so these should be changed to compare for not greater than
min_year. (While we're at it, we might as well make max_year symmetric.)
Second, the setboundaries function sets min_year and max_year based on
GMT, but these values are meant to be bounds for localtime years, so
to be safe one must subtract 1 from the GMT min year and add 1 to the
GMT max year. This is particularly important with the -s option,
since the GMT min year is 1970 but the localtime min year might be 1969.
Here is a proposed patch. This patch doesn't fix Sparks's bug, unfortunately.
1997-03-02 Paul Eggert <eggert at twinsun.com>
* zic.c (setboundaries): Set min_year to be one less than GMT
min_year, and max_year to be one greater than GMT max_year, in
case local time and GMT disagree about years at time boundaries.
(outzone, tadd): Don't assume that min_time and max_time are bounds
on time_t values, since -s makes this assumption false.
===================================================================
RCS file: RCS/zic.c,v
retrieving revision 1997.2.1.1
retrieving revision 1997.2.1.2
diff -c -r1997.2.1.1 -r1997.2.1.2
*** zic.c 1997/02/28 00:22:22 1997.2.1.1
--- zic.c 1997/03/03 03:58:26 1997.2.1.2
***************
*** 647,654 ****
max_time <<= TIME_T_BITS_IN_FILE - 1;
--max_time;
}
! min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
! max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
}
static int
--- 647,654 ----
max_time <<= TIME_T_BITS_IN_FILE - 1;
--max_time;
}
! min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year - 1;
! max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year + 1;
}
static int
***************
*** 1638,1645 ****
if (!rp->r_todisstd)
offset = oadd(offset, stdoff);
jtime = rp->r_temp;
! if (jtime == min_time ||
! jtime == max_time)
continue;
jtime = tadd(jtime, -offset);
if (k < 0 || jtime < ktime) {
--- 1638,1645 ----
if (!rp->r_todisstd)
offset = oadd(offset, stdoff);
jtime = rp->r_temp;
! if (jtime <= min_time ||
! jtime >= max_time)
continue;
jtime = tadd(jtime, -offset);
if (k < 0 || jtime < ktime) {
***************
*** 1978,1986 ****
{
register time_t t;
! if (t1 == max_time && t2 > 0)
return max_time;
! if (t1 == min_time && t2 < 0)
return min_time;
t = t1 + t2;
if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
--- 1978,1986 ----
{
register time_t t;
! if (t1 >= max_time && t2 > 0)
return max_time;
! if (t1 <= min_time && t2 < 0)
return min_time;
t = t1 + t2;
if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
More information about the tz
mailing list