Link Break Is it that time of the week again already? You've reached Line Break, our weekly roundup of terrible code you've seen in the wild. Today, we're going to delve into submissions from reader comments rather than the usual postbag.
Line Break article comments are such a rich seam of snippets and anecdotes, it would remiss to not surface a few from the hundreds posted so far.
Please do keep my inbox topped up with examples of hot source you've encountered. I hope to share them all with everyone in this software engineering group therapy.
Pass the swear jar
Many years ago I worked at a Well Known Daily Newspaper (begins with "I"). A colleague was writing a pre-processor for text input to the prepress page makeup system, all based on good ol' SunOS. Naturally, he was using C, as any good Unix coder back then would do, if he wanted something fast.
He put printf()s in liberally to help initial debugging, then took them out one by one. All was well until he took the last one out, whereupon his code died each time. He put it back in: it worked fine.
After a day of poking around, this was assigned to a "mysterious compiler timing problem" (code for "no idea"). He then proceeded to work out the minimum number of characters it had to printf in order to work.
The ops team were very surprised when, the first time this was used in production, the console window printed:
f u c k <space> i t <cr> = 8 characters.
A developer writes a critical routine that takes a datetime parameter. This routine eventually gets called from hundreds of locations all over the system. Often it's actually passed a datetime value, but sometimes it gets a variant and sometimes it just gets a string. VB says "that's cool, just pass any old thing and I'll make it work".
Years pass, and it starts to become clear that there are some bad dates in the system. It turns out that VB's way of turning strings into dates is to ignore the system locale and try to guess what the format might be. Pass in "25/12/2015" and it correctly assumes DMY and returns 25 December, but when it sees "10/12/2015" it returns 12 October! Finding the bad calls is more or less impossible, given the lack of VB code analysis tools.
The cause of this problem is a thing called cdate() that lives deep inside the run-time infrastructure. It turns out that the only way to fix it is to add code that patches the run-time after it's loaded into memory, not something you really want to do on a mission-critical server.
Thank you, Microsoft.
This is why we can't have nice things.
I've got all the time in the world – not
I regret that I do not have the source code to the most horrible bug I have ever found. The project involved using DSPs to send position data regularly by radio (pre-GSM), but with each radio transmitting at a different time. I had the time from GPS, so synchronization was easy. Apart from a little assembly language for the signal processing, the bulk of the code was in C. The kit worked fine in the office. Hours of testing with no problems at all. On the next day, I took it to the customer for a demonstration, and the kit sat there doing nothing.
After some frantic bug hunting I discovered the fault was in the C library for the DSP. The 32-bit add function was made out of a pair of signed 16-bit shifted add instructions. The DSP was massively optimised for 16-bit variables and fixed point arithmetic. CHAR_MAX was 32767 (sizeof(char)==1 by definition in C). As a result, almost all of my C code used 16-bit (int) variables and long int was only ever used for the time. During testing, bit 15 was zero, but the demonstration was at a time when bit 15 was 1.
The easy bit was fixing the code during the customer's lunch break. The difficult bit was explaining what I had fixed.
Glad you were able to go from zero to hero, Flocke.
That's how the cookie crumbles
Never trust the client: a company's website was defaced over the weekend. Their login system was all custom made so we looked into how it worked. Some pseudocode:
$userId = login($username, $password); if($userId != 0) // login success cookie_set('userId', $userId); // later on in other pages if(!cookie_isSet('userId')) die('You must be logged in'); $userId = cookie('userId');
I guess the developers never knew about PHP sessions and thought they could trust the users' cookies. It was pretty clear at this point how they were defaced so easily.
Don't let the user simply tell you who they are: they have to prove it. You can't let someone supply the username post authentication: use a session cookie to track the login. This reminds me of an online publishing system I used in the early 2000s that allowed the user to control the username of a submitted article comment. Oh the fun as people spoofed others on the message boards. You wouldn't do that?
Would you? ®