Versions Compared

Key

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

...

In this noncompliant example, the insert() function adds values to a buffer in a modulo fashion, that is, by inserting values at the beginning of the buffer once the end is reached. However, both size and index are declared as int and, consequently, not guaranteed to be positive. Depending on the implementation and on the sign of size and index, the result of (index + 1) % size may be negative, resulting in a write outside the bounds of the list array.

Code Block
bgColor#FFCCCC
langc
int insert(int index, int *list, int size, int value) {
  if (size != 0) {
    index = (index + 1) % size;
    list[index] = value;
    return index;
  }
  else {
    return -1;
  }
}

...

Taking the absolute value of the modulo operation returns a positive value:

Code Block
bgColor#FFCCCC
langc
int insert(int index, int *list, int size, int value) {
  if (size != 0) {
    index = abs((index + 1) % size);
    list[index] = value;
    return index;
  }
  else {
    return -1;
  }
}

...

The most appropriate solution in this case is to use unsigned types to eliminate any possible implementation defined behavior, as in this compliant solution. For compliance with recommendation ERR02-C, we fill a 'result' argument with the mathematical result, and we return nonzero only if the operation succeeds.

Code Block
bgColor#ccccff
langc
int insert(size_t* result, size_t index, int *list, size_t size, int value) {
  if (size != 0 && size != SIZE_MAX) {
    index = (index + 1) % size;
    list[index] = value;
    *result = index;
    return 1;
  }
  else {
    return 0;
  }
}

...