[tz] localtime.c bugs

Arthur David Olson arthurdavidolson at gmail.com
Tue Jul 10 19:23:41 UTC 2012


Hmmm...if a binary file has 32-bit values that are in sort and that all
have their
high-order bits set, it might be because it contains signed values that are
all
pre-epoch. It might also be because it contains unsigned values that are all
post-2038--that's unlikely now, but likelier as time goes by.

If we're lucky, 32-bit systems will be a thing of the past by the time it's
likely.
That being so, I've attached a slightly-revised version of Doug Bailey's
fixes
(they also appear below, with tabs mangled by Firefox/Gmail).

Are there any present-day systems with unsigned 64-bit time_t's?

        --ado

8.17
2110 lines
8.18
2127 lines
*** /tmp/,alocaltime.c    2012-07-10 15:14:38.372363200 -0400
--- /tmp/,blocaltime.c    2012-07-10 15:14:38.509371000 -0400
***************
*** 5,11 ****

  #ifndef lint
  #ifndef NOID
! static char    elsieid[] = "@(#)localtime.c    8.17";
  #endif /* !defined NOID */
  #endif /* !defined lint */

--- 5,11 ----

  #ifndef lint
  #ifndef NOID
! static char    elsieid[] = "@(#)localtime.c    8.18";
  #endif /* !defined NOID */
  #endif /* !defined lint */

***************
*** 277,282 ****
--- 277,287 ----
      /*
      ** And to get the latest zone names into tzname. . .
      */
+     for (i = 0; i < sp->typecnt; ++i) {
+         register const struct ttinfo * const    ttisp = &sp->ttis[i];
+
+         tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
+     }
      for (i = 0; i < sp->timecnt; ++i) {
          register const struct ttinfo * const    ttisp =
                              &sp->ttis[
***************
*** 489,508 ****
          ** signed time_t system but using a data file with
          ** unsigned values (or vice versa).
          */
!         for (i = 0; i < sp->timecnt - 2; ++i)
!             if (sp->ats[i] > sp->ats[i + 1]) {
!                 ++i;
                  if (TYPE_SIGNED(time_t)) {
                      /*
                      ** Ignore the end (easy).
                      */
!                     sp->timecnt = i;
                  } else {
                      /*
                      ** Ignore the beginning (harder).
                      */
                      register int    j;

                      for (j = 0; j + i < sp->timecnt; ++j) {
                          sp->ats[j] = sp->ats[j + i];
                          sp->types[j] = sp->types[j + i];
--- 494,525 ----
          ** signed time_t system but using a data file with
          ** unsigned values (or vice versa).
          */
!         for (i = 0; i < sp->timecnt; ++i)
!             if ((i < sp->timecnt - 1 &&
!                 sp->ats[i] > sp->ats[i + 1]) ||
!                 (i == sp->timecnt - 1 &&
!                 !TYPE_SIGNED(time_t) &&
!                 stored == 4 &&
!                 sp->ats[i] > INT32_MAX)) {
                  if (TYPE_SIGNED(time_t)) {
                      /*
                      ** Ignore the end (easy).
                      */
!                     sp->timecnt = i + 1;
                  } else {
                      /*
                      ** Ignore the beginning (harder).
                      */
                      register int    j;

+                     /*
+                     ** Keep the record right before the
+                     ** epoch boundary,
+                     ** but tweak it so that it starts
+                     ** right with the epoch
+                     ** (thanks to Doug Bailey).
+                     */
+                     sp->ats[i] = 0;
                      for (j = 0; j + i < sp->timecnt; ++j) {
                          sp->ats[j] = sp->ats[j + i];
                          sp->types[j] = sp->types[j + i];
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mm.icann.org/pipermail/tz/attachments/20120710/77c53f44/attachment.html 
-------------- next part --------------
8.17
2110 lines
8.18
2127 lines
*** /tmp/,alocaltime.c	2012-07-10 15:14:38.372363200 -0400
--- /tmp/,blocaltime.c	2012-07-10 15:14:38.509371000 -0400
***************
*** 5,11 ****
  
  #ifndef lint
  #ifndef NOID
! static char	elsieid[] = "@(#)localtime.c	8.17";
  #endif /* !defined NOID */
  #endif /* !defined lint */
  
--- 5,11 ----
  
  #ifndef lint
  #ifndef NOID
! static char	elsieid[] = "@(#)localtime.c	8.18";
  #endif /* !defined NOID */
  #endif /* !defined lint */
  
***************
*** 277,282 ****
--- 277,287 ----
  	/*
  	** And to get the latest zone names into tzname. . .
  	*/
+ 	for (i = 0; i < sp->typecnt; ++i) {
+ 		register const struct ttinfo * const	ttisp = &sp->ttis[i];
+ 
+ 		tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
+ 	}	
  	for (i = 0; i < sp->timecnt; ++i) {
  		register const struct ttinfo * const	ttisp =
  							&sp->ttis[
***************
*** 489,508 ****
  		** signed time_t system but using a data file with
  		** unsigned values (or vice versa).
  		*/
! 		for (i = 0; i < sp->timecnt - 2; ++i)
! 			if (sp->ats[i] > sp->ats[i + 1]) {
! 				++i;
  				if (TYPE_SIGNED(time_t)) {
  					/*
  					** Ignore the end (easy).
  					*/
! 					sp->timecnt = i;
  				} else {
  					/*
  					** Ignore the beginning (harder).
  					*/
  					register int	j;
  
  					for (j = 0; j + i < sp->timecnt; ++j) {
  						sp->ats[j] = sp->ats[j + i];
  						sp->types[j] = sp->types[j + i];
--- 494,525 ----
  		** signed time_t system but using a data file with
  		** unsigned values (or vice versa).
  		*/
! 		for (i = 0; i < sp->timecnt; ++i)
! 			if ((i < sp->timecnt - 1 &&
! 			    sp->ats[i] > sp->ats[i + 1]) ||
! 			    (i == sp->timecnt - 1 &&
! 			    !TYPE_SIGNED(time_t) &&
! 			    stored == 4 &&
! 			    sp->ats[i] > INT32_MAX)) {
  				if (TYPE_SIGNED(time_t)) {
  					/*
  					** Ignore the end (easy).
  					*/
! 					sp->timecnt = i + 1;
  				} else {
  					/*
  					** Ignore the beginning (harder).
  					*/
  					register int	j;
  
+ 					/*
+ 					** Keep the record right before the
+ 					** epoch boundary,
+ 					** but tweak it so that it starts
+ 					** right with the epoch
+ 					** (thanks to Doug Bailey).
+ 					*/
+ 					sp->ats[i] = 0;
  					for (j = 0; j + i < sp->timecnt; ++j) {
  						sp->ats[j] = sp->ats[j + i];
  						sp->types[j] = sp->types[j + i];


More information about the tz mailing list