string::assign(const char* s, size_t n) uses memcpy to copy new data into its buffer. This is invalid when the first argument points inside the string buffer. Example:
#include <string>
std::string s = "adasdsadasdsadsadasdasdsadsad";
void f(void) {
volatile int n = s.size();
s.assign((char*)s.data() + 0x10, n - 0x10);
}
int main(void) {
s.append(s);
f();
volatile int z = s.size();
return 0;
}
AFAIU, C++ standard allows such use.
Build this with g++ -O0 -g -fno-builtin and run under Valgrind.
Source and destination overlap in memcpy(0x5e240c0, 0x5e240d0, 42)
at 0x4C2C774: memcpy
by 0x4018C7: stlp_std::__char_traits_base<char, int>::copy(char*, char const*, unsigned long)
by 0x4014E1: stlp_std::basic_string<char, stlp_std::char_traits<char>, stlp_std::allocator<char> >::_M_assign(char const*, char const*)
by 0x4012DF: stlp_std::basic_string<char, stlp_std::char_traits<char>, stlp_std::allocator<char> >::assign(char const*, unsigned long)
by 0x400E20: f()
by 0x400E43: main
Tested with STLport-5.2.1.
Please, show me reference to authoritative opinion that this is a fair string usage.
Extra references to similar issues:
http://sourceforge.net/tracker/?func=detail&aid=1914475&group_id=146814&atid=766246
http://sourceforge.net/tracker/?func=detail&aid=1674974&group_id=146814&atid=766244
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Why not? The closest I found in the standard is
21.4.1:
6 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated
by the following uses of that basic_string object:
— as an argument to any standard library function taking a reference to non-const basic_string as an
argument.237
— Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and
rend.
AFAIU this means that element references become invalid after calls to string methods (other then the listed ones). Passing it as an argument to any string methods, including mutating methods, is valid, otherwise a lot of common usages will be incorrect.
21.4.6.3 basic_string::assign
basic_string& assign(const charT* s, size_type n);
8 Requires: s points to an array of at least n elements of charT.
9 Throws: length_error if n > max_size().
10 Effects: Replaces the string controlled by *this with a string of length n whose elements are a copy
of those pointed to by s.
11 Returns: *this.
Nothing here.