Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: modulo behavior in unsigned left shift is now permittted

...

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
bgColor#ccccff
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
bgColor#FFcccc
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
bgColor#ccccff
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.

...