8000 Duplicate string value if owned by the JsonBuffer · ROMSDEV/ArduinoJson@6f3f541 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6f3f541

Browse files
committed
Duplicate string value if owned by the JsonBuffer
1 parent ef1672d commit 6f3f541

File tree

5 files changed

+33
-9
lines changed

5 files changed

+33
-9
lines changed

src/ArduinoJson/Data/DynamicJsonBuffer.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ class DynamicJsonBufferBase : public JsonBuffer {
6969
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
7070
}
7171

72+
virtual bool owns(const void* ptr) const {
73+
for (const Block* b = _head; b; b = b->next) {
74+
if (ptr >= b->data && ptr < b->data + b->capacity) return true;
75+
}
76+
return false;
77+
}
78+
7279
// Resets the buffer.
7380
// USE WITH CAUTION: this invalidates all previously allocated data
7481
void clear() {

src/ArduinoJson/Data/JsonBuffer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class JsonBuffer : Internals::NonCopyable {
4747
// Return a pointer to the allocated memory or NULL if allocation fails.
4848
virtual void *alloc(size_t size) = 0;
4949

50+
virtual bool owns(const void *ptr) const = 0;
51+
5052
protected:
5153
// CAUTION: NO VIRTUAL DESTRUCTOR!
5254
// If we add a virtual constructor the Arduino compiler will add malloc()

src/ArduinoJson/Data/StaticJsonBuffer.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class StaticJsonBufferBase : public JsonBuffer {
6262
return doAlloc(bytes);
6363
}
6464

65+
virtual bool owns(const void* ptr) const {
66+
return ptr >= _buffer && ptr < _buffer + _size;
67+
}
68+
6569
// Resets the buffer.
6670
// USE WITH CAUTION: this invalidates all previously allocated data
6771
void clear() {

src/ArduinoJson/JsonVariantImpl.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,17 @@ inline JsonVariant &JsonVariant::operator=(const JsonVariant &variant) {
6161
using namespace Internals;
6262
if (variant.is<JsonArray>()) return operator=(variant.as<JsonArray>());
6363
if (variant.is<JsonObject>()) return operator=(variant.as<JsonObject>());
64-
_content = variant._content;
65-
_type = variant._type;
64+
if (variant.is<char *>()) {
65+
const char *str = variant.as<char *>();
66+
if (variant._buffer->owns(str)) {
67+
str = _buffer->strdup(str);
68+
}
69+
_type = JSON_STRING;
70+
_content.asString = str;
71+
} else {
72+
_content = variant._content;
73+
_type = variant._type;
74+
}
6675
return *this;
6776
}
6877

test/JsonArray/copy.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,27 @@
88
#include <ArduinoJson.h>
99
#include <catch.hpp>
1010

11+
static const size_t SIZE = JSON_ARRAY_SIZE(3) + 2 * JSON_OBJECT_SIZE(1) + 8;
12+
1113
template <typename TArray>
1214
TArray buildArray() {
1315
TArray array;
1416
array.add(42);
15-
array.createNestedObject()["hello"] = "world";
17+
array.createNestedObject()["abcdefg"] = "abcdefg";
18+
array.createNestedObject()["ABCDEFG"] = std::string("ABCDEFG");
1619
return array;
1720
}
1821

1922
template <typename TArray>
2023
void validateArray(TArray& array) {
21-
CHECK(array.size() == 2);
24+
CHECK(array.size() == 3);
2225
REQUIRE(array[0] == 42);
2326
REQUIRE(array[1].template is<JsonObject>());
24-
REQUIRE(array[1]["hello"] == std::string("world"));
27+
REQUIRE(array[1]["abcdefg"] == std::string("abcdefg"));
28+
REQUIRE(array[2].template is<JsonObject>());
29+
REQUIRE(array[2]["ABCDEFG"] == std::string("ABCDEFG"));
2530

26-
const size_t expectedSize = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1);
27-
REQUIRE(expectedSize == array.memoryUsage());
31+
REQUIRE(SIZE == array.memoryUsage());
2832
}
2933

3034
TEST_CASE("DynamicJsonArray::operator=()") {
@@ -38,14 +42,12 @@ TEST_CASE("DynamicJsonArray::operator=()") {
3842
}
3943

4044
SECTION("operator=(const StaticJsonArray<N>&)") {
41-
const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1);
4245
array = buildArray<StaticJsonArray<SIZE> >();
4346
validateArray(array);
4447
}
4548
}
4649

4750
TEST_CASE("StaticJsonArray::operator=()") {
48-
const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1);
4951
StaticJsonArray<SIZE> array;
5052
array.add(666);
5153
array.add(666);

0 commit comments

Comments
 (0)
0