mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
Fix String.replace overlapping strcpy (#5966)
* Fix String.replace overlapping strcpy Fixes #5949 Adds a test from the issue above and fixes the problem valgrind found. Additional pathological memcpy->memmove fixes
This commit is contained in:
parent
4b596d8fb1
commit
9712170276
@ -237,7 +237,7 @@ void String::move(String &rhs) {
|
|||||||
}
|
}
|
||||||
if (rhs.sso()) {
|
if (rhs.sso()) {
|
||||||
setSSO(true);
|
setSSO(true);
|
||||||
memcpy(sso_buf, rhs.sso_buf, sizeof(sso_buf));
|
memmove(sso_buf, rhs.sso_buf, sizeof(sso_buf));
|
||||||
} else {
|
} else {
|
||||||
setSSO(false);
|
setSSO(false);
|
||||||
setBuffer(rhs.wbuffer());
|
setBuffer(rhs.wbuffer());
|
||||||
@ -730,21 +730,21 @@ void String::replace(const String& find, const String& replace) {
|
|||||||
char *foundAt;
|
char *foundAt;
|
||||||
if(diff == 0) {
|
if(diff == 0) {
|
||||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||||
memcpy(foundAt, replace.buffer(), replace.len());
|
memmove(foundAt, replace.buffer(), replace.len());
|
||||||
readFrom = foundAt + replace.len();
|
readFrom = foundAt + replace.len();
|
||||||
}
|
}
|
||||||
} else if(diff < 0) {
|
} else if(diff < 0) {
|
||||||
char *writeTo = wbuffer();
|
char *writeTo = wbuffer();
|
||||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||||
unsigned int n = foundAt - readFrom;
|
unsigned int n = foundAt - readFrom;
|
||||||
memcpy(writeTo, readFrom, n);
|
memmove(writeTo, readFrom, n);
|
||||||
writeTo += n;
|
writeTo += n;
|
||||||
memcpy(writeTo, replace.buffer(), replace.len());
|
memmove(writeTo, replace.buffer(), replace.len());
|
||||||
writeTo += replace.len();
|
writeTo += replace.len();
|
||||||
readFrom = foundAt + find.len();
|
readFrom = foundAt + find.len();
|
||||||
setLen(len() + diff);
|
setLen(len() + diff);
|
||||||
}
|
}
|
||||||
strcpy(writeTo, readFrom);
|
memmove(writeTo, readFrom, strlen(readFrom)+1);
|
||||||
} else {
|
} else {
|
||||||
unsigned int size = len(); // compute size needed for result
|
unsigned int size = len(); // compute size needed for result
|
||||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||||
@ -760,7 +760,7 @@ void String::replace(const String& find, const String& replace) {
|
|||||||
readFrom = wbuffer() + index + find.len();
|
readFrom = wbuffer() + index + find.len();
|
||||||
memmove(readFrom + diff, readFrom, len() - (readFrom - buffer()));
|
memmove(readFrom + diff, readFrom, len() - (readFrom - buffer()));
|
||||||
int newLen = len() + diff;
|
int newLen = len() + diff;
|
||||||
memcpy(wbuffer() + index, replace.buffer(), replace.len());
|
memmove(wbuffer() + index, replace.buffer(), replace.len());
|
||||||
setLen(newLen);
|
setLen(newLen);
|
||||||
wbuffer()[newLen] = 0;
|
wbuffer()[newLen] = 0;
|
||||||
index--;
|
index--;
|
||||||
|
@ -428,3 +428,15 @@ TEST_CASE("String SSO handles junk in memory", "[core][String]")
|
|||||||
REQUIRE(*s == "CO2_defect");
|
REQUIRE(*s == "CO2_defect");
|
||||||
s->~String();
|
s->~String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Issue #5949 - Overlapping src/dest in replace", "[core][String]")
|
||||||
|
{
|
||||||
|
String blah = "blah";
|
||||||
|
blah.replace("xx", "y");
|
||||||
|
REQUIRE(blah == "blah");
|
||||||
|
blah.replace("x", "yy");
|
||||||
|
REQUIRE(blah == "blah");
|
||||||
|
blah.replace(blah, blah);
|
||||||
|
REQUIRE(blah == "blah");
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user