Computers Don’t Know Algebra
Take a look at this piece of code:
if( length + 4 < length )
return;
Algebraically, it's always false. "A number plus 1 can never be less than the number itself, that's a fundamental property of addition!"
Computers, however, are not perfect mathematical number crunchers as we've all been trained to believe. When you are writing software, you need to be aware of the environment that you are programming in. Not everything that's true in the outside world is true in the inside.
Magic Trick
There's a common magic trick that goes something like this:
- Pick a number
- Multiply it by 4
- Add 8
- Divide by 4
- Subtract your original number.
I know what you're thinking…it's 2!
Aside from being psychic, I also know middle school algebra. Say my number is x:
x
4*x
4*x+8
(4*x+8)/4
(4*x+8)/4 – x
Now simplify:
(4*x+8)/4 – x
x+2 – x
2
No matter what value you pick for x, you will always get 2.
At least, that's how it works in the real world. In the computing world, it doesn't work that way all the time. A college computer science class may mention the reason in passing, but it probably doesn't underline it.
A Code Example
Our "magic" trick would look something like this in code:
unsigned char x, guess;
cin >> x;
guess = x;
guess *= 4;
guess += 8;
guess /= 4;
guess -= x;
cout << guess;
So what could I enter in for x that would make guess not equal to 2?
How about 64? In the real world, 64*4=256. But in the computer world, an unsigned char can only hold up to 255. So what happens when I try and stuff 256 into guess? The extra bit gets cut off and we're left with 0!
Oops.
(4*64+8)/4-64
(0+8)/4-64
8/4-64
2-64
Now what's 2-64? No, it's not -62, our value is unsigned. Now it becomes 194!
Know Your Environment
Integer overflows are an all too common mistake and they are practically invisible. A compiler won't flag them, you can't always see them and your program may just keep chugging along without any indication that something is drastically wrong. So why is this code so important:
if( length + 4 < length )
return;
length += 4;
…
It verifies that length plus 4 will not overflow before doing the addition. If it would overflow, then length+4 will be less than length and the function can be aborted. Depending on what length is used for and where it comes from depends on how critical it is to check for overflows. Integer overflows can be the cause of major security headaches, be aware of how processors process the information and instructions you give it. Even though you are shielded from most low level operations in high level languages like C# and Java, you can still shoot yourself in the foot if you don't consider basic computer science knowledge in your everyday work.
The best way to see these kinds of problems is to test edge cases. Testing can reveal what your analysis has missed.
*This posting is provided "AS IS" with no warranties, and confers no rights.*