...
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 - | yes |
| ?: | no |
Although unsigned left shift <<
can result in wrapping, modulo behavior is permitted by this standard because of common usage, because this behavior is usually expected by the programmer, and because the behavior is well-defined.
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).
...
Code Block | ||
---|---|---|
| ||
pen->num_vertices = _cairo_pen_vertices_needed(
gstate->tolerance, radius, &gstate->ctm
);
if (pen->num_vertices > SIZE_MAX/sizeof(cairo_pen_vertex_t)) {
/* handle error condition */
}
pen->vertices = malloc(
pen->num_vertices * sizeof(cairo_pen_vertex_t)
);
|
...
Left-Shift Operator
The left-shift is between two operands of integer type.
Noncompliant Code Example
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
This compliant solution tests the operands of the left shift to guarantee there is no possibility of unsigned wrap. This solution must also be compliant with INT34-C. Do not shift a negative number of bits or more bits than exist in the operand.
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; } |
Exceptions
INT30-EX1. Unsigned integers can exhibit modulo behavior (wrapping) only when this behavior is necessary for the proper execution of the program. It is recommended that the variable declaration be clearly commented as supporting modulo behavior and that each operation on that integer also be clearly commented as supporting modulo behavior.
...