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