Browse Source

Fix inconsistent pool size in `BasicJsonDocument`'s copy constructor

Benoit Blanchon 4 years ago
parent
commit
b06bbd9d2a
3 changed files with 20 additions and 5 deletions
  1. 1 0
      CHANGELOG.md
  2. 14 0
      extras/tests/JsonDocument/swap.cpp
  3. 5 5
      src/ArduinoJson/Document/BasicJsonDocument.hpp

+ 1 - 0
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)
 -------

+ 14 - 0
extras/tests/JsonDocument/swap.cpp

@@ -1,6 +1,7 @@
 #include <ArduinoJson.h>
 
 #include <catch.hpp>
+#include <string>
 #include <utility>
 
 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<string>() == "world");
+    CHECK(doc2.capacity() == 0x10);
+    CHECK(doc2.as<string>() == "hello");
+  }
 }

+ 5 - 5
src/ArduinoJson/Document/BasicJsonDocument.hpp

@@ -98,7 +98,9 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
 
   template <typename T>
   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<TAllocator>, public JsonDocument {
     return MemoryPool(reinterpret_cast<char*>(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<TAllocator>, public JsonDocument {
   }
 
   void copyAssignFrom(const JsonDocument& src) {
-    reallocPoolIfTooSmall(src.capacity());
+    reallocPool(src.capacity());
     set(src);
   }