Versions Compared

Key

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

...

The index operators:

...

std::string index operators const_reference

...

operator[](size_type

...

)

...

const

...

 and reference

...

operator[](size_type

...

return ) return the character stored at the specified position if , pos < size(). If When pos =>= size(), the const
version returns the terminating null character type value. Otherwise, the behavior is undefined.In any case, the behavior of the index operators is a reference to an object of type charT with value charT() is returned. The index operators are unchecked (no exceptions are thrown for range errors).

Non-Compliant Example

The behavior of this non-compliant example is undefined becuase the size() of bs is 8 but the index used to reference bs ranges from 0 through 99.

Code Block

string bs("01234567");
for (int i=0; i<100; i++) {
  bs[i] = 'X';
}

This program does not typically raise an exception and is likely to crash.

Compliant Solution

Wiki Markup
The following compliant solution uses the {{basic_string at()}} method which behaves in a similar fashion to the index {{operator\[\]}} but throws an {{out_of_range}} if {{pos >= size()}}.

, and attempting to modify the resulting out-of-range object results in undefined behavior.

Similarly, the std::string::back() and std::string::front() functions are unchecked as they are defined to call through to the appropriate operator[]() without throwing.

Do not pass an out-of-range value as an argument to std::string::operator[](). Similarly, do not call std::string::back() or std::string::front() on an empty string. This rule is a specific instance of CTR50-CPP. Guarantee that container indices and iterators are within the valid range.

Noncompliant Code Example

In this noncompliant code example, the value returned by the call to get_index() may be greater than the number of elements stored in the string, resulting in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <string>
 
extern std::size_t get_index();
 
void f() {
  std::string s("01234567");
  s[get_index()] = '1';
}

Compliant Solution (try/catch)

This compliant solution uses the std::basic_string::at() function, which behaves in a similar fashion to the index operator[] but throws a std::out_of_range exception if pos >= size().

Code Block
bgColor#ccccff
langcpp
#include <stdexcept>
#include <string>
extern std::size_t get_index();

void f() {
  std::string s
Code Block

string bs("01234567");
  try {
   for (int i=0; i<100; i++) {
    bs.at(i) = '\0';
  }
}
catch (...) {
  cerr << "Index out of range" << endl;
}

...

s.at(get_index()) = '1';
  } catch (std::out_of_range &) {
    // Handle error
  }
}

Compliant Solution (Range Check)

This compliant solution checks that the value returned by get_index() is within a valid range before calling operator[]().

Code Block
bgColor#ccccff
langcpp
#include <string>

extern std::size_t get_index();

void f() {
  std::string s("01234567");
  std::size_t i = get_index();
  if (i < s.length()) {
    s[i] = '1';
  } else {
    // Handle error
  }
}

Noncompliant Code Example

This noncompliant code example attempts to replace the initial character in the string with a capitalized equivalent. However, if the given string is empty, the behavior is undefined.

Code Block
bgColor#FFcccc
langcpp
#include <string>
#include <locale>

void capitalize(std::string &s) {
  std::locale loc;
  s.front() = std::use_facet<std::ctype<char>>(loc).toupper(s.front());
}

Compliant Solution

In this compliant solution, the call to std::string::front() is made only if the string is not empty.

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

void capitalize(std::string &s) {
  if (s.empty()) {
    return;
  }

  std::locale loc;
  s.front() = std::use_facet<std::ctype<char>>(loc).toupper(s.front());
}

Risk Assessment

Unchecked element access can lead to out-of-bounds read bound reads and writes and write-anywhere exploits. These exploits can, in turn, lead to the execution of arbitrary code with the permissions of the vulnerable process.

References

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR53-CPP

High

Unlikely

Medium

P6

L2

Automated Detection

Tool

Version

Checker

Description

Astrée

Include Page
Astrée_V
Astrée_V

assert_failure

CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.MEM.BO
LANG.MEM.BU
LANG.MEM.TBA
LANG.MEM.TO
LANG.MEM.TU

Buffer overrun
Buffer underrun
Tainted buffer access
Type overrun
Type underrun
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C++3162, C++3163, C++3164, C++3165


Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_CPP-STR53-a

Guarantee that container indices are within the valid range

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: STR53-CPP

Checks for:

  • Array access out of bounds
  • Array access with tainted index
  • Pointer dereference with tainted offset

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.5, "basic_string Element Access"

[Seacord 2013]Chapter 2, "Strings"


...

Image Added Image Added Image Added Section 21.3.4 basic_string element access