Versions Compared

Key

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

...

This non-compliant example copies the null-terminated byte string input into the string email, replacing ';' characters with spaces. This example is non-compliant 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
char input[] = "bogus@addr.com; cat /etc/passwd";
string email;
string::iterator loc = email.begin();

// copy into string converting ";" to " "
for (size_t i=0; i <= strlen(input); i++) {
  if (input[i] != ';') {
    email.insert(loc++, input[i]);
  }
  else {
    email.insert(loc++, ' ');
  }
} // end string for each element in NTBS

...

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

Code Block
bgColor#ccccff
langcpp
char input[] = "bogus@addr.com; cat /etc/passwd";
string email;
string::iterator loc = email.begin();

// copy into string converting ";" to " "
for (size_t i=0; i <= strlen(input); i++) {
  if (input[i] != ';') {
    loc = email.insert(loc, input[i]);
  }
  else {
    loc = email.insert(loc, ' ');
  }
  ++loc;
} // end string for each element in NTBS

...

In this non-compliant example, the string s is initialized as "rcs" and the string iterator si is initialized to the beginning of the string. The size of s is three, and we'll assume the capacity is fifteen. The for loop appends 20 characters to the end of the sting. As a result, the si iterator is invalidated because the capacity of the string is exceeded, requiring a reallocation. As a result, the call to insert() results in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
string s("rcs");
string::iterator si = s.begin();

for (size_t i=0; i<20; ++i) {
  s.push_back('x');
}
s.insert(si, '*');

...

In this compliant solution, the non-compliant example is modified to only append capacity-size characters to the string s. As a result, the call to push_back() no longer invalidates the iterator.

Code Block
bgColor#ccccff
langcpp
string s("rcs");
string::iterator si = s.begin();

for (size_t i=0; i < 20; ++i) {
   if ( s.size() == s.capacity() ) {
     break;
   }
  s.push_back('x');
}
s.insert(si, '*');

...