More errata than sendmail
jm February 26th, 2007
A couple of interesting errata, courtesy of Herr Doktor Professor rCs:
First, on page 273, we discuss the somewhat counter-intuitive behavior of C’s arithmetic right shift. In the book, we say that when a signed integer variable is right-shifted, an arithmetic shift is performed, which means that the sign bit is propagated throughout the shift. So, with something like this:
int jim = 0x80000000;
printf("%Xn", jim >> 16);
If the right shift is arithmetic, jim is going to be 0xFFFF8000. If it’s logical, jim is going to be 0×00008000.
The mistake we made in the book is that the behavior of a signed right-shift is actually implementation-defined. So, it’s up to the compiler whether or not it’s arithmetic or logical. C99 says the following in Section 6.5.7, Bitwise shift operators, paragraph 5:
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.
The C99 Rationale document says the following in 6.5.7:
35 The C89 Committee affirmed the freedom in implementation granted by K&R in not requiring the signed right shift operation to sign extend, since such a requirement might slow down fast code and since the usefulness of sign extended shifts is marginal. (Shifting a negative two’s complement integer arithmetically right one place is not the same as dividing by two!)
Second, the diagram on page 517 is incorrect. It seems to indicate that a file that is the target of a symbolic link has its link count incremented. This is quite incorrect, as the link count only tracks hard links. This was strictly a mistake in the diagram, and the discussion surrounding it should be correct. The revised diagram would look something like this:

I am not fully sure but I guess the example on page 317-319 (Listing 7-9 and 7-10) is not correct - or to be more precious: it is wrong wrong.
In read_blob and process_packet ntohl() is used on a pointer to retrieve the needed length … why? This is just wrong, but perhaps you have another implementation of ntohl() than me. Even if it’s a typo and it should be “ntohl(*blob)” it is still wrong: blob would be filled in host order, so you end up with a way too big value anyway.
Now I assume this code snipplet would be right and an unsigned char is converted from network byte order to host byte order: the values can only be 0 - 255 because it is unsigned char. This fits in signed int. I think there is no way to create a negative integer out of it.
How could I “say with confidence that this comparison can be evaded”?
Nope, you’re right. That was a mistake in those two code snippets that we didn’t catch before the book went to print. I noticed it a couple months back and made two entries on the errata page. If you look there, you’ll see that what we intended was something that would read in an arbitrary int from the user, not ntohl(). It should be corrected in the second printing. Thanks, and let us know if you spot any more mistakes.