소스 검색

Fixed deserializeJson() when input contains duplicate keys (fixes #1095)

Benoit Blanchon 6 년 전
부모
커밋
a37480eec9
3개의 변경된 파일14개의 추가작업 그리고 6개의 파일을 삭제
  1. 1 0
      CHANGELOG.md
  2. 1 0
      extras/tests/JsonDeserializer/object.cpp
  3. 12 6
      src/ArduinoJson/Json/JsonDeserializer.hpp

+ 1 - 0
CHANGELOG.md

@@ -6,6 +6,7 @@ HEAD
 
 * Added support for custom writer classes (issue #1088)
 * Added conversion from `JsonArray` and `JsonObject` to `bool`, to be consistent with `JsonVariant`
+* Fixed `deserializeJson()` when input contains duplicate keys (issue #1095)
 
 v6.12.0 (2019-09-05)
 -------

+ 1 - 0
extras/tests/JsonDeserializer/object.cpp

@@ -277,6 +277,7 @@ TEST_CASE("deserialize JSON object") {
       DeserializationError err = deserializeJson(doc, "{a:{b:{c:1}},a:2}");
 
       REQUIRE(err == DeserializationError::Ok);
+      REQUIRE(doc["a"] == 2);
     }
   }
 

+ 12 - 6
src/ArduinoJson/Json/JsonDeserializer.hpp

@@ -130,15 +130,21 @@ class JsonDeserializer {
 
     // Read each key value pair
     for (;;) {
-      // Allocate slot in object
-      VariantSlot *slot = object.addSlot(_pool);
-      if (!slot) return DeserializationError::NoMemory;
-
       // Parse key
       const char *key;
       err = parseKey(key);
       if (err) return err;
-      slot->setOwnedKey(make_not_null(key));
+
+      VariantData *variant = object.get(adaptString(key));
+      if (!variant) {
+        // Allocate slot in object
+        VariantSlot *slot = object.addSlot(_pool);
+        if (!slot) return DeserializationError::NoMemory;
+
+        slot->setOwnedKey(make_not_null(key));
+
+        variant = slot->data();
+      }
 
       // Skip spaces
       err = skipSpacesAndComments();
@@ -147,7 +153,7 @@ class JsonDeserializer {
 
       // Parse value
       _nestingLimit--;
-      err = parseVariant(*slot->data());
+      err = parseVariant(*variant);
       _nestingLimit++;
       if (err) return err;