problem with detzcode on machines w/64 bit longs

Bradley White bww at fore.com
Fri Mar 10 13:59:30 UTC 1995


> Chris Demetriou, who maintains the NetBSD DEC Alpha port, reported a
> problem in localtime.c's detzcode() function that occurs because the
> value being extracted from the string in that function is not sign 
> extended properly.
> 
> He says: 
> 	The problem is that if you do what the current version does,
> 	then you can end up with numbers like 0xffffyyyy being
> 	returned from detzcode(), i.e. no sign extension into the
> 	upper 32 bits of the long.  Because of this, among other
> 	things, 'date' will say that it's some time in the year
> 	2025...
> 
> Using the following detzcode() implementation (which unrolls the loop
> and doesn't mask the first character) works, but it suffers from a 
> small defect in that it assumes signed characters.
> 
> 	static long
> 	detzcode(codep)
> 	const char * const      codep;
> 	{
> 		register long   result;
> 
> 		result = (codep[0] << 24) \
> 		       | (codep[1] & 0xff) << 16 \
> 		       | (codep[2] & 0xff) << 8
> 		       | (codep[3] & 0xff);
> 		return result;
> 	}
> 
> casting codep[0] to signed char would fix that, but would require a
> ANSI compiler.

How about this simple change?

*** tz95b/localtime.c	Sat Mar  4 11:22:26 1995
--- localtime.c	Fri Mar 10 08:51:53 1995
***************
*** 186,200 ****
  static long
  detzcode(codep)
  const char * const	codep;
  {
  	register long	result;
  	register int	i;
  
! 	result = 0;
  	for (i = 0; i < 4; ++i)
  		result = (result << 8) | (codep[i] & 0xff);
  	return result;
  }
  
  static void
  settzname P((void))
--- 186,200 ----
  static long
  detzcode(codep)
  const char * const	codep;
  {
  	register long	result;
  	register int	i;
  
! 	result = ~0;
  	for (i = 0; i < 4; ++i)
  		result = (result << 8) | (codep[i] & 0xff);
  	return result;
  }
  
  static void
  settzname P((void))



More information about the tz mailing list