Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fix the std::vector example and rewrote the explanation to be clearer.

...

In this noncompliant code example, a std::vector is used in place of a pointer and size pair. The function performs a range check to ensure that pos does not exceed the upper bound of the container but fails to check the lower bound for table. Because pos is declared as a (signed) intlong long, this parameter can assume a negative value. On systems where std::vector::size_type is ultimately implemented as an unsigned int (such as with Microsoft Visual Studio 2013), the usual arithmetic conversions applied for the comparison expression will convert the unsigned value to a signed value. If pos has a negative value, this comparison will not fail, resulting in a write outside the bounds of the std::vector object when the negative value is interpreted as a large unsigned value in the indexing operator.

Code Block
bgColor#ffcccc
langcpp
#include <vector>
 
void insert_in_table(std::vector<int> &table, intlong long pos, int value) {
  if (pos >= table.size()) {
    // Handle error
    return;
  }
  table[pos] = value;
}

...

In this compliant solution, the parameter pos is declared as size_t, which prevents passing of negative arguments (see INT01-CPP. Use rsize_t or size_t for all integer values representing the size of an object).ensures that the comparison expression will fail when a large, positive value (converted from a negative argument) is given:

Code Block
bgColor#ccccff
langcpp
#include <vector>
 
void insert_in_table(std::vector<int> &table, std::size_t pos, int value) {
  if (pos >= table.size()) {
    // Handle error
    return;
  }
  table[pos] = value;
}

...