ITER.RANGE.INVALID

Use of invalid iterator range

The ITER checkers find problems with iterators in containers. The ITER.RANGE.INVALID checker flags invalid iterator ranges passed to C++ STL algorithms. A valid range [first, last) requires both iterators to refer to the same container, the first iterator not to follow the second in the container sequence, and neither iterator to be singular or otherwise invalid for the operation.

Vulnerability and risk

Using an invalid iterator range can result in undefined behavior. Reversed ranges can cause an STL algorithm to increment past the end of a container, and iterator pairs from different containers can cause out-of-bounds access or nonterminating iteration. The consequences can include memory corruption, information disclosure, and unexpected program behavior.

Mitigation and prevention

Pass begin() before end() when you specify an iterator range. Ensure both iterators come from the same container instance, and use a valid empty range only when the iterators are equivalent.

Vulnerable code example

Copy
#include <algorithm>
#include <iostream>
#include <vector>

void f(const std::vector<int> &c)
{
  std::for_each(c.end(), c.begin(), [](int i) { std::cout << i; });
}

In this example, the end iterator is passed before the begin iterator. The algorithm increments the first iterator until it matches the second, so incrementing the end iterator results in undefined behavior.

Fixed code example

Copy
#include <algorithm>
#include <iostream>
#include <vector>

void f(const std::vector<int> &c)
{
  std::for_each(c.begin(), c.end(), [](int i) { std::cout << i; });
}

In the fixed example, the iterators are passed in the correct order.

Vulnerable code example

Copy
#include <algorithm>
#include <iostream>
#include <vector>

void f(const std::vector<int> &c)
{
  std::vector<int>::const_iterator e;
  std::for_each(c.begin(), e, [](int i) { std::cout << i; });
}

In this example, the second iterator is default-initialized and does not come from container c. Because the two iterators do not form a valid range, the algorithm can behave unpredictably.

Fixed code example

Copy
#include <algorithm>
#include <iostream>
#include <vector>

void f(const std::vector<int> &c)
{
  std::for_each(c.begin(), c.end(), [](int i) { std::cout << i; });
}

In the fixed example, both iterators come from the same container.

Extension

NA