From b06bbd9d2a9b8e6eb0d48602e107c53e1aa9689b Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 23 Nov 2021 10:49:35 +0100 Subject: [PATCH] Fix inconsistent pool size in `BasicJsonDocument`'s copy constructor --- CHANGELOG.md | 1 + extras/tests/JsonDocument/swap.cpp | 14 ++++++++++++++ src/ArduinoJson/Document/BasicJsonDocument.hpp | 10 +++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90759f4c..7082f38e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ HEAD * Remove `DeserializationError == bool` and `DeserializationError != bool` * Fix `JsonVariant::memoryUsage()` for raw strings * Fix `call of overloaded 'swap(BasicJsonDocument&, BasicJsonDocument&)' is ambiguous` (issue #1678) +* Fix inconsistent pool size in `BasicJsonDocument`'s copy constructor v6.18.5 (2021-09-28) ------- diff --git a/extras/tests/JsonDocument/swap.cpp b/extras/tests/JsonDocument/swap.cpp index 85be575b..60d672f8 100644 --- a/extras/tests/JsonDocument/swap.cpp +++ b/extras/tests/JsonDocument/swap.cpp @@ -1,6 +1,7 @@ #include #include +#include #include using namespace std; @@ -10,4 +11,17 @@ TEST_CASE("std::swap") { DynamicJsonDocument *p1, *p2; swap(p1, p2); // issue #1678 } + + SECTION("DynamicJsonDocument") { + DynamicJsonDocument doc1(0x10), doc2(0x20); + doc1.set("hello"); + doc2.set("world"); + + swap(doc1, doc2); + + CHECK(doc1.capacity() == 0x20); + CHECK(doc1.as() == "world"); + CHECK(doc2.capacity() == 0x10); + CHECK(doc2.as() == "hello"); + } } diff --git a/src/ArduinoJson/Document/BasicJsonDocument.hpp b/src/ArduinoJson/Document/BasicJsonDocument.hpp index 5c85d8a7..2f7b382f 100644 --- a/src/ArduinoJson/Document/BasicJsonDocument.hpp +++ b/src/ArduinoJson/Document/BasicJsonDocument.hpp @@ -98,7 +98,9 @@ class BasicJsonDocument : AllocatorOwner, public JsonDocument { template BasicJsonDocument& operator=(const T& src) { - reallocPoolIfTooSmall(src.memoryUsage()); + size_t requiredSize = src.memoryUsage(); + if (requiredSize > capacity()) + reallocPool(requiredSize); set(src); return *this; } @@ -136,9 +138,7 @@ class BasicJsonDocument : AllocatorOwner, public JsonDocument { return MemoryPool(reinterpret_cast(this->allocate(capa)), capa); } - void reallocPoolIfTooSmall(size_t requiredSize) { - if (requiredSize <= capacity()) - return; + void reallocPool(size_t requiredSize) { freePool(); replacePool(allocPool(addPadding(requiredSize))); } @@ -148,7 +148,7 @@ class BasicJsonDocument : AllocatorOwner, public JsonDocument { } void copyAssignFrom(const JsonDocument& src) { - reallocPoolIfTooSmall(src.capacity()); + reallocPool(src.capacity()); set(src); }