Monday, January 12, 2015

CRLF ≠ LFCR

I thought it would be an easy and quick project for last night to go back and properly fix the CRLF problem I was having. Unfortunately, it was not. I spent hours and hours testing the HTTP input string, hex-dumping, debugging, testing, and comparing strings using the lwip's built-in data compare functions. I still could not find what was going wrong. I started losing faith in the lwip code, the MPW complier, the Motorola 68000 processor, all of computer science. Was this really happening? It is getting so late, am I dreaming?

Finally, I double-checked a hex dump on the string to search for: "\r\n" and it reported: 0x0a 0x0d. At first, I thought 'that looks right', but then I noticed that it should be returning 0x0d 0x0a instead! How could it be transposing these predefined character escape sequences? A quick search on google revealed the problem: MPW transposes these two standard escape characters by default. I could't believe it. Of course, it is documented in the Apple SC/SCpp Reference for the MPW C/C++ compiler:

The compiler will by default map \n to the value 10 and \r to the value 13 to conform to the MPW environment. The -noMapCR option will turn off the mapping of the newline to carriage-return and carriage-return to newline.
If you are familiar with Macintosh line breaks (CR only), this makes sense, but if you are familiar with ANSI C code, it does not.

In the context of the lwIP web server, it was erroneously looking for 2 LFCRs, but wouldn't get them until there were 3 CRLFs: CR[LFCRLFCR]LF. Once I regained my sanity, the fix was easy:
/* #define CRLF "\r\n" */ /* WTF? I hate computers... */ #define CRLF "\x0d\x0a"

Compiler character mapping quirks, swapped characters and pulling hair out all seem to be themes in the RetroChallenge.

No comments:

Post a Comment