[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