From 21b2c76524f65d8cd0823223d3ce0a5bbcba3821 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 13 Jan 2022 16:12:56 +0100 Subject: [PATCH] Fix filter not working in zero-copy mode (fixes #1697) --- CHANGELOG.md | 1 + extras/tests/JsonDeserializer/filter.cpp | 14 ++++++++++++++ extras/tests/JsonDeserializer/object.cpp | 16 ++++++++++++++++ extras/tests/MsgPackDeserializer/filter.cpp | 14 ++++++++++++++ src/ArduinoJson/StringStorage/StringMover.hpp | 2 +- 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0ff97fd..bdae248e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Fix crash when adding an object member in a too small `JsonDocument` +* Fix filter not working in zero-copy mode (issue #1697) v6.19.0 (2022-01-08) ------- diff --git a/extras/tests/JsonDeserializer/filter.cpp b/extras/tests/JsonDeserializer/filter.cpp index b460d050..e950f768 100644 --- a/extras/tests/JsonDeserializer/filter.cpp +++ b/extras/tests/JsonDeserializer/filter.cpp @@ -667,6 +667,20 @@ TEST_CASE("Filtering") { } } +TEST_CASE("Zero-copy mode") { // issue #1697 + char input[] = "{\"include\":42,\"exclude\":666}"; + + StaticJsonDocument<256> filter; + filter["include"] = true; + + StaticJsonDocument<256> doc; + DeserializationError err = + deserializeJson(doc, input, DeserializationOption::Filter(filter)); + + REQUIRE(err == DeserializationError::Ok); + CHECK(doc.as() == "{\"include\":42}"); +} + TEST_CASE("Overloads") { StaticJsonDocument<256> doc; StaticJsonDocument<256> filter; diff --git a/extras/tests/JsonDeserializer/object.cpp b/extras/tests/JsonDeserializer/object.cpp index 61ddbd7a..e5d5de7f 100644 --- a/extras/tests/JsonDeserializer/object.cpp +++ b/extras/tests/JsonDeserializer/object.cpp @@ -279,6 +279,22 @@ TEST_CASE("deserialize JSON object") { REQUIRE(err == DeserializationError::Ok); REQUIRE(doc["a"] == 2); } + + SECTION("Repeated key with zero copy mode") { // issue #1697 + char input[] = "{a:{b:{c:1}},a:2}"; + DeserializationError err = deserializeJson(doc, input); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc["a"] == 2); + } + + SECTION("NUL in keys") { // we don't support NULs in keys + DeserializationError err = + deserializeJson(doc, "{\"x\\u0000a\":1,\"x\\u0000b\":2}"); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.as() == "{\"x\":2}"); + } } SECTION("Should clear the JsonObject") { diff --git a/extras/tests/MsgPackDeserializer/filter.cpp b/extras/tests/MsgPackDeserializer/filter.cpp index e923a37f..583c42f8 100644 --- a/extras/tests/MsgPackDeserializer/filter.cpp +++ b/extras/tests/MsgPackDeserializer/filter.cpp @@ -1027,6 +1027,20 @@ TEST_CASE("deserializeMsgPack() filter") { } } +TEST_CASE("Zero-copy mode") { // issue #1697 + char input[] = "\x82\xA7include\x01\xA6ignore\x02"; + + StaticJsonDocument<256> filter; + filter["include"] = true; + + StaticJsonDocument<256> doc; + DeserializationError err = + deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter)); + + CHECK(err == DeserializationError::Ok); + CHECK(doc.as() == "{\"include\":1}"); +} + TEST_CASE("Overloads") { StaticJsonDocument<256> doc; StaticJsonDocument<256> filter; diff --git a/src/ArduinoJson/StringStorage/StringMover.hpp b/src/ArduinoJson/StringStorage/StringMover.hpp index e862ff07..4ed7d92e 100644 --- a/src/ArduinoJson/StringStorage/StringMover.hpp +++ b/src/ArduinoJson/StringStorage/StringMover.hpp @@ -18,7 +18,6 @@ class StringMover { } FORCE_INLINE String save() { - _writePtr[0] = 0; // terminator String s = str(); _writePtr++; return s; @@ -33,6 +32,7 @@ class StringMover { } String str() const { + _writePtr[0] = 0; // terminator return String(_startPtr, size(), true); }