zdump -v crashes with 64-bit time_t
Paul Eggert
eggert at CS.UCLA.EDU
Thu Jun 17 21:16:16 UTC 2004
"Olson, Arthur David (NIH/NCI)" <olsona at dc37a.nci.nih.gov> writes:
> It might be better to cut off at something such as...
> 2050 + 100 * ((current_year - 1930) / 100)
> ...to ease regression testing
Good point; here's a further patch to implement this. I fixed a
couple of other minor problems with outlandishly large years that I
noticed while composing this change.
===================================================================
RCS file: RCS/zdump.8,v
retrieving revision 2004.1.0.1
retrieving revision 2004.1.0.2
diff -pc -r2004.1.0.1 -r2004.1.0.2
*** zdump.8 2004/06/15 05:24:21 2004.1.0.1
--- zdump.8 2004/06/17 21:10:14 2004.1.0.2
*************** otherwise.
*** 40,46 ****
.TP
.BI "\-c " cutoffyear
Cut off the verbose output near the start of the given year.
! By default, verbose output is cut off approximately 50 years after the
current date and time.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
--- 40,46 ----
.TP
.BI "\-c " cutoffyear
Cut off the verbose output near the start of the given year.
! By default, verbose output is cut off a few decades after the
current date and time.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
===================================================================
RCS file: RCS/zdump.c,v
retrieving revision 2003.3.0.2
retrieving revision 2003.3.0.4
diff -pc -r2003.3.0.2 -r2003.3.0.4
*** zdump.c 2004/06/15 05:24:21 2003.3.0.2
--- zdump.c 2004/06/17 21:12:39 2003.3.0.4
*************** char * argv[];
*** 170,176 ****
register int c;
register int vflag;
register char * cutoff;
! register int cutyear;
register time_t lasttime;
char ** fakeenv;
time_t now;
--- 170,177 ----
register int c;
register int vflag;
register char * cutoff;
! register long cutyear;
! long y;
register time_t lasttime;
char ** fakeenv;
time_t now;
*************** _("%s: usage is %s [ --version ] [ -v ]
*** 216,241 ****
time_t_min = TYPE_SIGNED(time_t) ? hibit : 0;
(void) time(&now);
if (cutoff != NULL) {
! int y;
!
! cutyear = atoi(cutoff);
! lasttime = 0;
! for (y = EPOCH_YEAR; y < cutyear; ++y)
! lasttime += DAYSPERNYEAR + isleap(y);
! lasttime *= SECSPERHOUR * HOURSPERDAY;
! lasttime -= TYPE_SIGNED(time_t) || lasttime != 0;
} else {
/*
** By default, the cutoff is the maximum time value,
! ** or about 50 years from now, whichever comes first.
** This prevents us from generating too much output if
! ** time_t is 64 bits. 31556952 is 365.2425 * 24 * 60
! ** * 60, but don't trust the C compiler to calculate
! ** it as there may be bugs or rounding problems.
*/
! long seconds_per_mean_gregorian_year = 31556952;
! time_t now50 = now + 50 * seconds_per_mean_gregorian_year - 1;
! lasttime = now < now50 ? now50 : time_t_max;
}
longest = 0;
for (i = optind; i < argc; ++i)
--- 217,247 ----
time_t_min = TYPE_SIGNED(time_t) ? hibit : 0;
(void) time(&now);
if (cutoff != NULL) {
! cutyear = atol(cutoff);
} else {
/*
** By default, the cutoff is the maximum time value,
! ** or a few decades from now, whichever comes first.
** This prevents us from generating too much output if
! ** time_t is wider than 32 bits.
*/
! newtm = gmtime (&now);
! if (newtm == NULL)
! cutyear = now < 0 ? LONG_MIN : LONG_MAX;
! else {
! cutyear = newtm->tm_year + (long) TM_YEAR_BASE;
! cutyear = 2050 + 100 * ((cutyear - 1930) / 100);
! }
! }
! lasttime = 0;
! for (y = EPOCH_YEAR; y < cutyear; ++y) {
! newt = lasttime - !lasttime;
! newt += (DAYSPERNYEAR + isleap(y)) * SECSPERHOUR * HOURSPERDAY;
! if (newt < lasttime) {
! lasttime = time_t_max;
! break;
! }
! lasttime = newt;
}
longest = 0;
for (i = optind; i < argc; ++i)
More information about the tz
mailing list