Check for NUL terminator in MemoryPool::findString()

This commit is contained in:
Benoit Blanchon
2021-11-20 20:30:24 +01:00
parent 43b2e2e774
commit a27398e445
9 changed files with 64 additions and 3 deletions

View File

@ -37,6 +37,12 @@ class String {
return *this; return *this;
} }
char operator[](unsigned int index) const {
if (index >= _str.size())
return 0;
return _str[index];
}
friend std::ostream& operator<<(std::ostream& lhs, const ::String& rhs) { friend std::ostream& operator<<(std::ostream& lhs, const ::String& rhs) {
lhs << rhs._str; lhs << rhs._str;
return lhs; return lhs;

View File

@ -166,9 +166,21 @@ class MemoryPool {
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
template <typename TAdaptedString> template <typename TAdaptedString>
const char* findString(const TAdaptedString& str) { static bool stringEquals(const char* p, size_t n, const TAdaptedString& s) {
for (char* next = _begin; next < _left; ++next) { if (p[n]) // check terminator first
if (str.compare(next) == 0) return false;
for (size_t i = 0; i < n; i++) {
if (p[i] != s[i])
return false;
}
return true;
}
template <typename TAdaptedString>
const char* findString(const TAdaptedString& str) const {
size_t n = str.size();
for (char* next = _begin; next + n < _left; ++next) {
if (stringEquals(next, n, str))
return next; return next;
// jump to next terminator // jump to next terminator

View File

@ -32,6 +32,11 @@ class StringAdapter< ::String> {
return safe_strcmp(me, other); return safe_strcmp(me, other);
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0);
return _str->operator[](static_cast<unsigned int>(i));
}
size_t size() const { size_t size() const {
return _str->length(); return _str->length();
} }

View File

@ -7,6 +7,7 @@
#include <stddef.h> // size_t #include <stddef.h> // size_t
#include <string.h> // strcmp #include <string.h> // strcmp
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Polyfills/safe_strcmp.hpp> #include <ArduinoJson/Polyfills/safe_strcmp.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp> #include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp> #include <ArduinoJson/Strings/StringAdapter.hpp>
@ -32,6 +33,12 @@ class StringAdapter<const char*> {
return strlen(_str); return strlen(_str);
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0);
ARDUINOJSON_ASSERT(i <= size());
return _str[i];
}
const char* data() const { const char* data() const {
return _str; return _str;
} }

View File

@ -39,6 +39,13 @@ class StringAdapter<const __FlashStringHelper*> {
return strlen_P(reinterpret_cast<const char*>(_str)); return strlen_P(reinterpret_cast<const char*>(_str));
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0);
ARDUINOJSON_ASSERT(i <= size());
return static_cast<char>(
pgm_read_byte(reinterpret_cast<const char*>(_str) + i));
}
typedef storage_policies::store_by_copy storage_policy; typedef storage_policies::store_by_copy storage_policy;
private: private:

View File

@ -34,6 +34,14 @@ class StringAdapter<const __FlashStringHelper*, true> {
memcpy_P(p, reinterpret_cast<const char*>(_str), n); memcpy_P(p, reinterpret_cast<const char*>(_str), n);
} }
// TODO: not covered by the tests
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0);
ARDUINOJSON_ASSERT(i <= _size);
return static_cast<char>(
pgm_read_byte(reinterpret_cast<const char*>(_str) + i));
}
size_t size() const { size_t size() const {
return _size; return _size;
} }

View File

@ -33,6 +33,12 @@ class StringAdapter<TChar*, true> {
return _size; return _size;
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0);
ARDUINOJSON_ASSERT(i <= _size);
return _str[i];
}
typedef storage_policies::store_by_copy storage_policy; typedef storage_policies::store_by_copy storage_policy;
private: private:

View File

@ -33,6 +33,11 @@ class StringAdapter<std::basic_string<char, TCharTraits, TAllocator> > {
return _str->compare(other); return _str->compare(other);
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(i <= size());
return _str->operator[](i);
}
size_t size() const { size_t size() const {
return _str->size(); return _str->size();
} }

View File

@ -31,6 +31,11 @@ class StringAdapter<std::string_view> {
return _str.compare(other); return _str.compare(other);
} }
char operator[](size_t i) const {
ARDUINOJSON_ASSERT(i <= size());
return _str[i];
}
size_t size() const { size_t size() const {
return _str.size(); return _str.size();
} }