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[]() overload without throwing.

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

Noncompliant Code Example

In this noncompliant code example, the value i may be greater than the number of elements stored in the string, resulting in undefined behavior:The behavior of this non-compliant example is undefined because the index i used to reference bs may be outside the range of bs. This could cause a write-out-of-bounds error.

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

bs[i s[get_index()] = '\01';

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


}

Compliant Solution (try/catch)

...

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

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

extern std::size_t get_index();

void f() {
  std::string s("01234567");
  try {
  size_t i = f();
  bs.at(i s.at(get_index()) = '\01';
  }
 catch (...std::out_of_range &) {
  cerr << "Index// outHandle oferror
 range" << endl; }
}

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#FFcccc#ccccff
langcpp
string bs#include <string>

extern std::size_t get_index();

void f() {
  std::string s("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 L;
  S.front() = std::use_facet<std::ctype<char>>(L).toupper(S.front());
}

Compliant Solution

In this compliant solution, the call to std::string::front() is only made if the string is not emptyUse 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' );

...

&S) {
  if (S.empty()) {
    return;
  }

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

Risk Assessment

Unchecked element access can lead to out-of-bounds 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-CPP

highHigh

likelyUnlikely

highMedium

P9P6

L2

Automated Detection

Tool

Version

Checker

Description

 PRQA QA-C++

   
Include Page
PRQA QA-C++_vPRQA QA-C++_v-wc "::std::vector::[]" 

Bibliography

...

Related Vulnerabilities

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

Related Guidelines

Bibliography

...

...

21.

...

4.

...

5, "basic_string

...

Element Access"

[Seacord 2013b]Chapter 2, "Strings"

...

STR38-CPP. Use valid references, pointers, and iterators to reference elements of a basic_string      07007. Characters and Strings (STR)      08008. Memory Management (MEM)