Main Content

CERT C++: CTR53-CPP

Use valid iterator ranges

Since R2022b

Description

Rule Definition

Use valid iterator ranges.1

Polyspace Implementation

The rule checker checks for Invalid iterator usage.

Examples

expand all

Issue

This issue occurs when the first and last iterators of a range do not correspond to the begin and end iterators of the same container. Consider this code:

std::vector v{0,1,2,3,4,5,6,7,8,9};
std::vector w{0,1,2,3,4,5,6,7,8,9};
//...
std::for_each(v.end(), v.begin(), [](int i){}); //Noncompliant
std::for_each(v.begin(), w.end(), [](int i){}); //Noncompliant
std::for_each(v.begin(), v.end(), [](int i){}); //Compliant 
Polyspace® reports a violation if the range does not begin and end with the begin and end iterator of the same container, such as v.begin() and v.end(). Polyspace checks for the invalid use of most iterators in the standard library. Invalid use of string iterators, such as std::string and std::string_view iterators are not reported.

Risk

  • Using an iterator range where the first and last iterators do not refer to the begin and end iterators of the same container results in undefined behavior. For instance, using v.begin() and w.end() to delimit a range might result in undefined behavior.

  • When you use the end iterator as the first point of a range, the compiler might attempt to access memory that is not part of the container. Accessing memory past the end iterator might result in undefined behavior.

Using such invalid iterator ranges might allow an attacker to run arbitrary code.

Fix

To fix violations this rule:

  • Use iterators from the same container when defining a range.

  • Use the begin iterator as the first element and the end iterator as the last element of the range.

Example — Invalid Iterator
#include <iostream>
#include <algorithm>
#include <map>

void foo(const std::map<int,int> &a, const std::map<int,int> &b) {
	std::for_each(a.rend(), a.rbegin(), [](std::pair<int,int> i) {  //Noncompliant   
	/*...*/});

	std::all_of(a.rbegin(), b.rend(), [](std::pair<int,int> i) {  //Noncompliant     
		return 0;});
}

In this example, Polyspace reports the invalid use of iterators:

  • In the call to the function std::for_each(), the range is delimited by using the a.rend() iterator first and a.rbegin() iterator next. The compiler might increment a.rend() and attempt to access memory that is not part of the container. Polyspace reports a violation.

  • In the call to the function std::all_of, the iterators a.rbegin and b.rend() delimits the range. Defining ranges by using two unrelated iterators is undefined behavior. Polyspace reports a violation.

Correction — Use Iterators From Same Container In Correct Order

To fix this issue, use iterators from the same container in the correct order when defining a range.

#include <iostream>
#include <algorithm>
#include <map>

void foo(const std::map<int,int> &a, const std::map<int,int> &b) {
	std::for_each(a.rbegin(), a.rend(), [](std::pair<int,int> i) {  //Compliant   
	/*...*/});

	std::all_of(b.rbegin(), b.rend(), [](std::pair<int,int> i) {  //Compliant     
		return 0;});
}

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.