Bug#402776: zdump -v errors on 64 bit architectures
Package: libc6.1
Version: 2.3.6.ds1-8
When I invoke 'zdump -v America/New_York' on a 32 bit architecture the
output is correct. But, when execuited on a 64 bit architecture the
first 2 lines of output and the last 2 lines are errors (the min and max
years).
The incorrect ouput on a 64 bit architecture has the last 4 lines
something like:
America/New_York Sun Nov 1 05:59:59 2037 UTC = Sun Nov 1 01:59:59
2037 EDT isdst=1 gmtoff=-14400
America/New_York Sun Nov 1 06:00:00 2037 UTC = Sun Nov 1 01:00:00
2037 EST isdst=0 gmtoff=-18000
America/New_York 9223372036854689407 = NULL
America/New_York 9223372036854775807 = NULL
but the corrected output has the last 4 lines ending correctly at year
2038 as seen here:
America/New_York Sun Nov 1 05:59:59 2037 UTC = Sun Nov 1 01:59:59
2037 EDT isdst=1 gmtoff=-14400
America/New_York Sun Nov 1 06:00:00 2037 UTC = Sun Nov 1 01:00:00
2037 EST isdst=0 gmtoff=-18000
America/New_York Mon Jan 18 03:14:07 2038 UTC = Sun Jan 17 22:14:07
2038 EST isdst=0 gmtoff=-18000
America/New_York Tue Jan 19 03:14:07 2038 UTC = Mon Jan 18 22:14:07
2038 EST isdst=0 gmtoff=-18000
The values may change but the '= NULL' is consistant when in error.
The problem is caused by an overflow in the year element of
the tm structure that is used. All elements, except year, of the
structure are safe because their max values are limited, ie. 60 seconds,
60 minutes... but years has no limits.
I have attached a patch for zdump.c that restricts the size of the
absolute max and min values used to compute the year value such that it
will not overflow on 64 bit architectures.
I am using Debian GNU/Linux 2.6.17-2-mckinley ia64
and libc6.1 2.3.6.dsl-8
--- zdump.c.orig 2006-12-11 13:59:19.000000000 -0500
+++ zdump.c 2006-12-11 13:59:27.000000000 -0500
@@ -416,12 +416,14 @@
/*
** time_t is signed.
*/
- register time_t hibit;
+ int hibit;
for (hibit = 1; (hibit * 2) != 0; hibit *= 2)
continue;
absolute_min_time = hibit;
absolute_max_time = -(hibit + 1);
+ if(sizeof(int) == 8)
+ absolute_max_time *= 64;
} else {
/*
** time_t is unsigned.
Reply to: