...
This behavior is more informally referred to as unsigned integer wrapping. Unsigned integer operations can wrap if the resulting value cannot be represented by the underlying representation of the integer. The following table indicates which operators can result in wrapping:.
Operator | Wrap |
| Operator | Wrap |
| Operator | Wrap |
| Operator | Wrap |
---|---|---|---|---|---|---|---|---|---|---|
yes |
| yes |
| yes |
| < | no | |||
yes |
| yes |
| >> | no |
| > | no | ||
yes |
| /= | no |
| & | no |
| >= | no | |
/ | no |
| %= | no |
| | | no |
| <= | no |
% | no |
| yes |
| ^ | no |
| == | no | |
++ | yes |
| >>= | no |
| ~ | no |
| != | no |
-- | yes |
| &= | no |
| ! | no |
| && | no |
= | no |
| |= | no |
| un + | no |
| || | no |
yes |
| ^= | no |
| un - | no yes |
| ?: | no |
The following sections examine specific operations that are susceptible to unsigned integer wrap. When operating on small integer types (smaller than int
), integer promotions are applied. The usual arithmetic conversions may also be applied to (implicitly) convert operands to equivalent types before arithmetic operations are performed. Make sure you understand integer conversion rules before trying to implement secure arithmetic operations (see INT02-C. Understand integer conversion rules).
...
- as an array index
- in any pointer arithmetic
- as a length or size of an object
- as the bound of an array (for example, a loop counter)
- as an argument to a memory allocation function
- in security-critical code
Anchor | ||||
---|---|---|---|---|
|
...
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, sum;
/* Initialize ui1 and ui2 */
sum = ui1 + ui2;
|
Compliant Solution
...
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, sum; /* Initialize ui1 and ui2 */ if (UINT_MAX - ui1 < ui2) { /* handle error condition */ } else { sum = ui1 + ui2; } |
Anchor | ||||
---|---|---|---|---|
|
...
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, result;
/* Initialize ui1 and ui2 */
result = ui1 - ui2;
|
Compliant Solution
...
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, result; /* Initialize ui1 and ui2 */ if (ui1 < ui2){ /* handle error condition */ } else { result = ui1 - ui2; } |
Anchor | ||||
---|---|---|---|---|
|
...
Anchor | ||||
---|---|---|---|---|
|
Left-Shift Operator
The left-shift operator is between two operands of integer type.
...
This noncompliant code example can result in unsigned wrap left-shifting the unsigned operand ui1
by ui2
bits.
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, uresult;
/* Initialize ui1 and ui2 */
uresult = ui1 << ui2;
|
Compliant Solution
...
Code Block | ||
---|---|---|
| ||
unsigned int ui1, ui2, uresult; /* Initialize ui1 and ui2 */ if ( (ui2 >= sizeof(unsigned int)*CHAR_BIT) || (ui1 > (UINT_MAX >> ui2))) ) { { /* handle error condition */ } else { uresult = ui1 << ui2; } |
...