1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Add memmove_P, use it in String to ensure F() safety (#6514)

memmove_P is now in libc, so use it to allow WString to handle F()
pointers without errors.

Supercedes #6368

Fixes #6384
This commit is contained in:
Earle F. Philhower, III 2019-09-13 15:33:16 -07:00 committed by GitHub
parent 990ec759f2
commit 8dd068eb40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 19 deletions

View File

@ -185,7 +185,7 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) {
size_t oldSize = capacity() + 1; // include NULL. size_t oldSize = capacity() + 1; // include NULL.
if (isSSO()) { if (isSSO()) {
// Copy the SSO buffer into allocated space // Copy the SSO buffer into allocated space
memmove(newbuffer, sso.buff, sizeof(sso.buff)); memmove_P(newbuffer, sso.buff, sizeof(sso.buff));
} }
if (newSize > oldSize) if (newSize > oldSize)
{ {
@ -210,7 +210,7 @@ String & String::copy(const char *cstr, unsigned int length) {
return *this; return *this;
} }
setLen(length); setLen(length);
memmove(wbuffer(), cstr, length + 1); memmove_P(wbuffer(), cstr, length + 1);
return *this; return *this;
} }
@ -228,7 +228,7 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
void String::move(String &rhs) { void String::move(String &rhs) {
if(buffer()) { if(buffer()) {
if(capacity() >= rhs.len()) { if(capacity() >= rhs.len()) {
memmove(wbuffer(), rhs.buffer(), rhs.length() + 1); memmove_P(wbuffer(), rhs.buffer(), rhs.length() + 1);
setLen(rhs.len()); setLen(rhs.len());
rhs.invalidate(); rhs.invalidate();
return; return;
@ -241,7 +241,7 @@ void String::move(String &rhs) {
} }
if (rhs.isSSO()) { if (rhs.isSSO()) {
setSSO(true); setSSO(true);
memmove(sso.buff, rhs.sso.buff, sizeof(sso.buff)); memmove_P(sso.buff, rhs.sso.buff, sizeof(sso.buff));
} else { } else {
setSSO(false); setSSO(false);
setBuffer(rhs.wbuffer()); setBuffer(rhs.wbuffer());
@ -313,7 +313,7 @@ unsigned char String::concat(const String &s) {
return 1; return 1;
if (!reserve(newlen)) if (!reserve(newlen))
return 0; return 0;
memmove(wbuffer() + len(), buffer(), len()); memmove_P(wbuffer() + len(), buffer(), len());
setLen(newlen); setLen(newlen);
wbuffer()[len()] = 0; wbuffer()[len()] = 0;
return 1; return 1;
@ -330,12 +330,7 @@ unsigned char String::concat(const char *cstr, unsigned int length) {
return 1; return 1;
if(!reserve(newlen)) if(!reserve(newlen))
return 0; return 0;
if (cstr >= wbuffer() && cstr < wbuffer() + len()) memmove_P(wbuffer() + len(), cstr, length + 1);
// 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); setLen(newlen);
return 1; return 1;
} }
@ -739,21 +734,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) {
memmove(foundAt, replace.buffer(), replace.len()); memmove_P(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;
memmove(writeTo, readFrom, n); memmove_P(writeTo, readFrom, n);
writeTo += n; writeTo += n;
memmove(writeTo, replace.buffer(), replace.len()); memmove_P(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);
} }
memmove(writeTo, readFrom, strlen(readFrom)+1); memmove_P(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) {
@ -767,9 +762,9 @@ void String::replace(const String& find, const String& replace) {
int index = len() - 1; int index = len() - 1;
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) { while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = wbuffer() + index + find.len(); readFrom = wbuffer() + index + find.len();
memmove(readFrom + diff, readFrom, len() - (readFrom - buffer())); memmove_P(readFrom + diff, readFrom, len() - (readFrom - buffer()));
int newLen = len() + diff; int newLen = len() + diff;
memmove(wbuffer() + index, replace.buffer(), replace.len()); memmove_P(wbuffer() + index, replace.buffer(), replace.len());
setLen(newLen); setLen(newLen);
wbuffer()[newLen] = 0; wbuffer()[newLen] = 0;
index--; index--;
@ -797,7 +792,7 @@ void String::remove(unsigned int index, unsigned int count) {
char *writeTo = wbuffer() + index; char *writeTo = wbuffer() + index;
unsigned int newlen = len() - count; unsigned int newlen = len() - count;
setLen(newlen); setLen(newlen);
memmove(writeTo, wbuffer() + index + count, newlen - index); memmove_P(writeTo, wbuffer() + index + count, newlen - index);
wbuffer()[newlen] = 0; wbuffer()[newlen] = 0;
} }
@ -829,7 +824,7 @@ void String::trim(void) {
unsigned int newlen = end + 1 - begin; unsigned int newlen = end + 1 - begin;
setLen(newlen); setLen(newlen);
if(begin > buffer()) if(begin > buffer())
memmove(wbuffer(), begin, newlen); memmove_P(wbuffer(), begin, newlen);
wbuffer()[newlen] = 0; wbuffer()[newlen] = 0;
} }

View File

@ -60,6 +60,7 @@ inline size_t strlen_P(const char *s) { return strlen(s); }
inline int vsnprintf_P(char *str, size_t size, const char *format, va_list ap) { return vsnprintf(str, size, format, ap); } inline int vsnprintf_P(char *str, size_t size, const char *format, va_list ap) { return vsnprintf(str, size, format, ap); }
#define memcpy_P memcpy #define memcpy_P memcpy
#define memmove_P memmove
#define strncpy_P strncpy #define strncpy_P strncpy
#define strcmp_P strcmp #define strcmp_P strcmp
#define memccpy_P memccpy #define memccpy_P memccpy

View File

@ -25,6 +25,7 @@ extern "C" {
int _EXFUN(memcmp_P,(const _PTR, const _PTR, size_t)); int _EXFUN(memcmp_P,(const _PTR, const _PTR, size_t));
_PTR _EXFUN(memmem_P, (const _PTR, size_t, const _PTR, size_t)); _PTR _EXFUN(memmem_P, (const _PTR, size_t, const _PTR, size_t));
_PTR _EXFUN(memcpy_P,(_PTR __restrict, const _PTR __restrict, size_t)); _PTR _EXFUN(memcpy_P,(_PTR __restrict, const _PTR __restrict, size_t));
_PTR _EXFUN(memmove_P,(_PTR __restrict, const _PTR __restrict, size_t));
_PTR _EXFUN(memccpy_P,(_PTR __restrict, const _PTR __restrict, int, size_t)); _PTR _EXFUN(memccpy_P,(_PTR __restrict, const _PTR __restrict, int, size_t));
_PTR _EXFUN(memchr_P,(const _PTR, int, size_t)); _PTR _EXFUN(memchr_P,(const _PTR, int, size_t));