Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

When performing pointer arithmetic, the size of the value to add to a pointer is automatically scaled to the size of the type of the pointed-to object. For instance, when adding a value to the byte address of a 4-byte integer, the value is scaled by a factor 4 of 4 and then added to the pointer. Failing to understand how pointer arithmetic works can lead to miscalculations that result in serious errors, such as buffer overflows.

...

In this compliant solution, the size of buf, INTBUFSIZE is added directly to buf and used as an upper bound. The integer literal INTBUFSIZE is scaled to the size of an integer, and the upper bound of buf is checked correctly.

...

An arguably better solution is to use the address of the nonexistent element following the end of the array, as follows:

Code Block
bgColor#CCCCFF
langc
int buf[INTBUFSIZE];
int *buf_ptr = buf;

while (havedata() && buf_ptr < &buf[INTBUFSIZE] {
  *buf_ptr++ = parseint(getdata());
}

This works because C99 guarantees because the C standard guarantees the address of buf[INTBUFSIZE] even though no such element exists.

...

The examples in this rule reflect both a correct and wrong way and an incorrect way to handle comparisons of numbers representing different things (either single bytes or multibyte data structures). The NCEs just The noncompliant examples just add the numbers without regard to units, whereas the compliant solutions use type casts to convert one number to the appropriate unit of the other number.

ROSE can catch both NCE's by both noncompliant examples by searching for pointer arithmetic expressions involving different units. The "different units" is the tricky part, but you can try to identify an expression's units using some simple heuristics:

  • A pointer to a foo object has foo as the unit.
  • A pointer to char * has byte as the unit byte.
  • Any sizeof or offsetof expression also has unit byte as the unit byte.
  • Any variable used in an index to an array of foo objects (e.g., foo[variable]) has foo as the unit.

In addition to pointer arithmetic expressions, one  you can also hunt for array index expressions, as array[index] is merely shorthand for "array + index."

...