[net.bugs.uucp] uucp portability bug

shannon (02/02/83)

There is a bug in the checksum routine in the packet driver
used with uucp.  This is a portability bug I found when porting
my uucp to the Sun.  The problem occurs when converting a variable
of type short to a variable of type unsigned int, where int and
short are not the same.  K&R (pg. 41) seems to imply that the
variable will first be sign extended to int and then converted
to unsigned, although I am not sure of that interpretation.  The
VAX C compiler seems to convert to unsigned, then to int (movzwl).
Our 68000 C compiler converts to int (extw), then treats the result
as unsigned in the expression below.  Anyway, here's the fixed
checksum routine for pk0.c:

chksum(s,n)
register char *s;
register n;
{
	register short sum;
	register unsigned short t;
	register short x;

	sum = -1;
	x = 0;

	do {
		if (sum<0) {
			sum <<= 1;
			sum++;
		} else
			sum <<= 1;
		t = sum;
		sum += (unsigned)*s++ & 0377;
		x += sum^n;
		if ((unsigned short)sum <= t) {			/***/
			sum ^= x;
		}
	} while (--n > 0);

	return(sum&0xffff);					/***/
}

Marked lines are changed.  There are probably other changes that
would make it more portable but those are the ones that made it
work.

					Bill Shannon
					sun!shannon