Versions Compared

Key

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

The Since std::basic_string is a container of characters, this rule is a specific instance of CTR51-CPP. Use valid references, pointers, and iterators to reference elements of a container. As a container, it supports iterators just like other containers in the Standard Template Library. However, the std::basic_string template class has unusual invalidation semantics. According to the The C++ Standard, [string.require], paragraph 5 [ISO/IEC 14882-2014], states the following:

References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:

  •  as As an argument to any standard library function taking a reference to non-const basic_string as an argument.
  • Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and rend.

Examples of standard library functions taking a reference to non-const std::basic_string are : std::swap(), ::operator>>(basic_istream &, string &), and std::getline().

Do not use a an invalidated reference, pointer, or iterator that has been invalidated, as that because doing so results in undefined behavior. This rule is a specific instance of CTR32-CPP. Use valid references, pointers, and iterators to reference elements of a container.

Noncompliant Code Example

This noncompliant code example copies input into a std::string, replacing ';' characters semicolon (;) characters with spaces. This example is noncompliant because the iterator loc is invalidated after the first call to insert(). The behavior of subsequent calls to insert() is undefined.

Code Block
bgColor#FFcccc
langcpp
#include <string>
 
void f(const std::string &input) {
  std::string email;
  std::string::iterator loc = email.begin();

  // copyCopy input into email converting ";" to " "
  std::string::iterator loc = email.begin();
  for (auto Ii = input.begin(), Ee = input.end(); Ii != Ee; ++Ii, ++loc) {
    email.insert(loc, *Ii != ';' ? *Ii : ' ');
  }
}

Compliant Solution (std::string::insert())

In this compliant solution, the value of the iterator loc is updated as a result of each call to insert() so that the invalidated iterator is never accessed. The updated iterator is then incremented at the end of the loop.

Code Block
bgColor#ccccff
langcpp
#include <string>
 
void f(const std::string &input) {
  std::string email;
  std::string::iterator loc = email.begin();

  // copyCopy input into email converting ";" to " "
  std::string::iterator loc = email.begin();
  for (auto Ii = input.begin(), Ee = input.end(); Ii != Ee; ++Ii, ++loc) {
    loc = email.insert(loc, *Ii != ';' ? *Ii : ' ');
  }
}

Compliant Solution (std::replace())

In this This compliant solution , the manual loop is replaced with uses a standard algorithm that performs to perform the replacement. Using generic algorithms is generally When possible, using a generic algorithm is preferable to inventing your own solution when possible.

Code Block
bgColor#ccccff
langcpp
#include <algorithm>
#include <string>
 
void f(const std::string &input) {
  std::string email{input};
  std::replace(email.begin(), email.end(), ';', ' ');
}

Noncompliant Code Example

In this noncompliant code example, data is invalidated after the call to replace(), and so its use in g() is undefined behavior.

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
#include <string>
 
extern void g(const char *);
 
void f(std::string &exampleString) {
  const char *data = exampleString.data();
  // ...
  exampleString.replace(0, 2, "bb");
  // ...
  g(data);
}

Compliant Solution

In this compliant solution, the pointer to exampleString's internal buffer is not generated until after the modification from replace() has completed.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <string>

extern void g(const char *);

void f(std::string &exampleString) {
  // ...
  exampleString.replace(0, 2, "bb");
  // ...
  g(exampleString.data());
}

Risk Assessment

Using an invalid reference, pointer, or iterator to a string object could allow an attacker to run arbitrary code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR38

STR52-CPP

High

Probable

High

P6

L2

Automated Detection

Tool

Version

Checker

Description

   

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

ALLOC.UAF

Use After Free

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

DF4746, DF4747, DF4748, DF4749


Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-STR52-a

Use valid references, pointers, and iterators to reference elements of a basic_string

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: STR52-CPPChecks for use of invalid string iterator (rule partially covered).
 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

Subclause 21.4.1, "basic_string General Requirements"

[Meyers
01
2001]Item 43
: Prefer algorithm calls to hand-written loops

 

, "Prefer Algorithm Calls to Hand-written Loops"


...

Image Added Image Added Image AddedImage Removed Image Removed Image Removed