[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: