Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in several String functions, out of bounds crash #9426

Closed
1 task done
TD-er opened this issue Mar 27, 2024 · 1 comment
Closed
1 task done

Bug in several String functions, out of bounds crash #9426

TD-er opened this issue Mar 27, 2024 · 1 comment
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@TD-er
Copy link
Contributor

TD-er commented Mar 27, 2024

Board

Any

Device Description

Hardware Configuration

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

Windows 11

Flash frequency

40MHz

PSRAM enabled

yes

Upload speed

115200

Description

See similar issue for ESP8266: esp8266/Arduino#9110

In several String functions, wbuffer()[N] is used where N might be the size of the allocated buffer.
For example: (line 313)

bool String::concat(const String &s) {
// Special case if we're concatting ourself (s += s;) since we may end up
// realloc'ing the buffer and moving s.buffer in the method called
if (&s == this) {
unsigned int newlen = 2 * len();
if (!s.buffer())
return false;
if (s.len() == 0)
return true;
if (!reserve(newlen))
return false;
memmove(wbuffer() + len(), buffer(), len());
setLen(newlen);
wbuffer()[len()] = 0;
return true;
} else {
return concat(s.buffer(), s.len());
}
}

And this part in String::replace:

while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = wbuffer() + index + find.len();
memmove(readFrom + diff, readFrom, len() - (readFrom - buffer()));
int newLen = len() + diff;
memmove(wbuffer() + index, replace.buffer(), replace.len());
setLen(newLen);
wbuffer()[newLen] = 0;
index--;
}

Also this one tries to copy past the allocated buffer:

String & String::copy(const char *cstr, unsigned int length) {
if(!reserve(length)) {
invalidate();
return *this;
}
memmove(wbuffer(), cstr, length + 1);
setLen(length);
return *this;
}

And this one: (lines 330 and 333)

bool String::concat(const char *cstr, unsigned int length) {
unsigned int newlen = len() + length;
if(!cstr)
return false;
if(length == 0)
return true;
if(!reserve(newlen))
return false;
if (cstr >= wbuffer() && cstr < wbuffer() + len())
// compatible with SSO in ram #6155 (case "x += x.c_str()")
memmove(wbuffer() + len(), cstr, length + 1);
else
// compatible with source in flash #6367
memcpy_P(wbuffer() + len(), cstr, length + 1);
setLen(newlen);
return true;
}

Maybe the simplest fix might be to adapt String::changeBuffer:

size_t newSize = (maxStrLen + 16 + 1) & (~0xf);

Sketch

-

Debug Message

-

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@TD-er TD-er added the Status: Awaiting triage Issue is waiting for triage label Mar 27, 2024
@TD-er
Copy link
Contributor Author

TD-er commented Mar 27, 2024

My assumption on size_t newSize = (maxStrLen + 16) & (~0xf); was incorrect, so I will close this issue till I found the real cause....

@TD-er TD-er closed this as completed Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

1 participant