by Edward
01 March 2009 01:08
The Wikipedia Definition: An integer overflow occurs when an arithmetic operation attempts to create a numeric value that is larger than can be represented within the available storage space. For instance, adding 1 to the largest value that can be represented constitutes an integer overflow. The most common result in these cases is for the least significant representable bits of the result to be stored (the result is said to wrap). On some processors like GPUs and DSPs, the result saturates, that is once the maximum value is reached attempts to make it larger simply return the maximum result.
The Developer Definition: Integer overflow is the generic name for a set of common integer arithmetic mistakes that can lead to Buffer Overruns.
Lets have a look at the following example:
int[] filter(uint len, int[] numbers)
{
uint newLen = len * 3/4;
int[] buf = new int[newLen];
int j = 0;
for(int i = 0; i < len; i++)
{
if (i % 4 != 0)
buf[j++] = numbers[i];
}
return buf;
}
What is wrong with the code above? The problem is that in calculating the value for len, the code first computes len * 3!
The program filters an array of int’s to have only ¾ of the original values.
-
Integer overflows are still possible in Managed Code.
- C# is no different from C in this regard
- VB.Net will throw System.Overflow exception
-
Result is often not as severe
- Integer overflows often result in buffer overflows which are much less likely with managed code
-
They can still lead to system instability issues
Integer Overflows Countermeasures
-
Take proper care in checking arithmetic
-
Never make assumptions about the largest value a variable will hold
-
Take care when executing in a loop -EG: x=x+1 can be bad if executed enough
-
Do sanity checks on values before they are used
-
Keep in mind how large or small the result of an arithmetic operation can be
-
Use the /checked compiler flag for C# projects -
Default in C# 2.0 (for example)
public Object GetUserData(UInt32 ItemNumber) {
checked {
return myData[ItemNumber+USER_DATA_START];
}
}