By now everyone has heard of the Heartbleed bug. Prior to that Apple had its “Goto Fail” bug. Magic tricks seem obvious once they have been explained. In the case of Heartbleed, the programmer forgot to put a limit on the amount of information that could be requested in a packet, thus exposing information that was nearby in memory, which could be the very information that a secure protocol is supposed to hide. In the case of Goto Fail, the admonition to always enclose blocks of code in braces, even if it is a single statement, was ignored, so that an extraneous goto statement ended up always being called, thus aborting the security checks that the protocol was designed to implement. These two high-profile software bugs have drawn attention to how the integrity of the Internet depends on some very obscure code written by some very obscure programmers. The Heartbleed code is in an implementation of the SSL security protocol and it is open source, meaning anyone can view the source code. This theoretically makes it easier to find bugs, but this is true both for the bad guys who want to exploit the bugs and the good guys who want to squash the bugs. The system works if there are more good guys looking at the code than bad guys Despite the immense profits corporations make from the Internet, these companies don’t spend much money to support the development of the underlying code that allows the Internet to function securely. It took two years for the good guys to find the Heartbleed bug (it’s not clear if or when the bad guys found out about it). I have a feeling more effort is going to be put into this now. Don’t be surprised if other similar bugs are discovered. This would be a good thing, because no complex software is bug-free, and bugs discovered can be fixed.
I had my own mini-Heartbleed bug recently. I don’t write mission-critical code, but still it is important to me that what I write works properly. A doctor wrote to me that my EP Mobile app had stopped working. He had an tablet running Android 4.3 and when he tapped on a item in the main menu, nothing happened. This was odd because the app worked on my phone and tablet, as well as on the simulators that come with the Android software development kit. The menu code was one of the first bits of code I had written, several years ago. I was new to Android programming at the time, and I think I basically copied it from one of my Android programming books. Reviewing the code, it seemed extremely straight-forward and simple. At first I couldn’t imagine what the problem could be.
Well, to make a long story short, and not to get too technical (and you can skip this paragraph if you don’t know/care about programming) the problem was in this code:
CharSequence selection = ((TextView) view).getText();
if (selection.equals(getString(R.string.calculator_list_title))) {
calculatorList();
} // etc.
This is code that shouldn’t work, but almost always does. The error is that selection
is a CharSequence
, which is not the same as a String
. Thus you shouldn’t be able to compare selection
with a String
using selection.equals()
. According to the Java standard, the results of such a comparison are undefined. The problem is that this code works — most of the time — even though it is erroneous. There is no error generated and everything seems to be hunky-dory until you get an email from a user who says that the app isn’t working. The solution is to convert the CharSequence
to a String
using the toString()
method. It seems easy in retrospect. The trick is figuring it out ahead of time.
Software is inherently fragile. A simple Google search finds lists of epic software fails, such as this one. The results of software mistakes range from mere embarrassment to the destruction of billion-dollar space missions or the death of patients from overdoses of radiation therapy. We entrust so much to software nowadays. All our medical records are in computer databases. Our financial transactions are online. Our cars and jets are computer controlled. It is sobering to think that a misplaced semi-colon or brace buried deep in some systems code somewhere could reveal my credit card information or worse make a plane fall out of the sky. Software, like a person, is inherently complex. We have to throw as many resources as possible towards improving it, including improving the tools we have to check for software errors. But we can’t expect perfection. We have to do the best we can.
Complexity is never simple.