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

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

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

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}} exception 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 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

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.

References

...

Related Guidelines

Bibliography

...

2014]

Subclause 21.

...

4.

...

5, "basic_string

...

Element Access"

[Seacord 2013]Chapter 2, "Strings"


...

Image Added Image Added Image Added