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 Code Example

, 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 behaviorThe behavior of this non-compliant example is undefined because the index i used to reference bs may be outside the range of bs, causing a write-out-of-bounds error.

Code Block
bgColor#FFcccc
langcpp
#include <string>
string bs 
extern std::size_t get_index();
 
void f() {
  std::string s("01234567");
size_t i = fs[get_index();

bs[i] = '\01';

This program does not typically raise an exception and may be exploited to overwrite memory at a specified location.

Compliant Solution

}

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:: Wiki MarkupThis compliant solution uses the {{basic_string at()}} method, which behaves in a similar fashion to the index {{operator\[\]}} but throws an {{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 bss("01234567");
  try {
  size_t i = f();
  bs s.at(iget_index()) = '\01';
  }
 catch (...std::out_of_range &) {
  cerr << "Index// outHandle oferror
 range" << endl; }
}

In any case, the behavior of the index operators is unchecked (no exceptions are thrown).

Non-Compliant Code Example

Compliant Solution (Range Check)

This compliant solution checks that the value returned by get_index() is within a valid range before calling operator[]()The behavior of this non-compliant example is undefined because the size() of bs is 8 but the index used to reference bs ranges from 0 through 99.

Code Block
bgColor#ccccff
lang#FFcccccpp
#include <string>

extern std::size_t get_index();

void f() {
  std::string s
string bs("01234567");
for (int  std::size_t i=0;  = get_index();
  if (i < 100; i++s.length()) {
  bs  s[i] = '\01';
  } else {
    // Handle error
  }

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

Compliant Solution

}

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.Use the fill algorithm to assign the value '\0' to evey element in the specified range:

Code Block
bgColor#ccccff
langcpp

size_t const max_fill = 100;
#include <string>
#include <locale>

void capitalize(std::string bs("01234567");

fill(bs.begin(), bs.begin()+std::min(max_fill, bs.length()), '\0' );

The range is specified as starting from the beginning of the string and ending at the minimum of the string length or the max_fill constant value of 100.

&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 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.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR39

STR53-

C

3 (high)

3 (likely)

1 (high)

P9

L2

References

Wiki Markup
\[[Seacord 05|AA. References#Seacord 05]\] Chapter 2 Strings
\[[ISO/IEC 14882-2003|AA. References#ISO/IEC 14882-2003]\] Section 21.3.4 basic_string element access

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 STR38-CPP. Use valid references, pointers, and iterators to reference string objects      07. Characters and Strings (STR)      STR43-CPP. Do not access the return value of c_str() after the original string goes out of scope