Main Content

CERT C++: CTR55-CPP

Do not use an additive operator on an iterator if the result would overflow

Since R2022b

Description

Rule Definition

Do not use an additive operator on an iterator if the result would overflow.1

Polyspace Implementation

The rule checker checks for Possible iterator overflow.

Examples

expand all

Issue

This issue occurs when:

  • A constant other than 1, 0, or -1 is added or subtracted from an iterator.

  • A variable that is assigned a value other than 1, 0, or -1 is added or subtracted from an iterator. The variable must be local in scope and unmodified before use.

Such operations might result in an iterator before the begin iterator or after the end iterator of a container. For instance:

void print_vec(const std::vector<int> &v) {
	auto end_it = v.begin()+20;//Noncompliant
	for (auto it = v.begin(); it != end_it; ++it) {
		//...
	}
}
The function print_vec does not check if the iterator end_it goes past v.end(). The operation v.begin()+20 might result in an iterator overflow. Polyspace® reports a violation on this operation.

Polyspace raises this violation for sequence containers such as std::vector, std::array, and std::deque. As an exception, Polyspace does not report a violation if iterators are incremented or decremented by using the pre or post increment or decrement operators.

Risk

The C++ standard does not guarantee the dereferencibility of iterators that are beyond the bounds of the container. An addition or subtraction operation that results in a possible iterator overflow cause an undefined behavior. Often, such an iterator overflow leads to a buffer overflow or buffer underrun. These defects might be exploited by an attacker to execute malicious code.

Fix

Validate the addition and subtraction operations on iterators so that the resultant iterators do not overflow.

Example — Avoid Addition Operation That Might Overflow on Iterators
#include<vector>
#include<string>
#include<iostream>
//Template function that accepts any container and prints the first 20 values
template<typename C, typename T = typename C::value_type>
void checkFirst20(C const& container)
{
  
  for(auto it = container.begin(), last = it+20; it!=last;++it)//Noncompliant
  {std::cout<<*it<<'\n';}
}

void foo(){
	std::vector<float> v(20);
	checkFirst20(v);
}

In this example, the function checkFirst20() calculates the value of the iterator last adding 20 to another iterator it. The code does not verify if last remains within the bounds of container. Dereferencing such an iterator might result in undefined behavior. Polyspace reports a violation of this rule on this addition.

Correction — Validate Addition Operation

To fix this issue, validate the addition operation that defines last so that the iterator does not point beyond the bounds of container. For instance, in the addition operation that defines last, use the smaller of 20 and the value container.size() so that last is within the bounds of container.

#include<vector>
#include<string>
#include<iostream>
//Template function that accepts any container and prints the first 20 values
template<typename C, typename T = typename C::value_type>
void printFirst20(C const& container)
{
 typename C::size_type max = 20;
  for(auto it = container.begin(), 
      last = it + std::min(max,container.size());
       it!=last;++it)//Compliant
  {std::cout<<*it<<'\n';}
}

void foo(){
	std::vector<float> v(5);
	printFirst20(v);
}

Check Information

Group: Rule 04. Containers (CTR)

Version History

Introduced in R2022b


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.