From 2be528a3fa3780f8e118b676dfea00009c07ee15 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 29 Apr 2021 20:59:15 +0200 Subject: [PATCH] serializeMsgPack(doc, p, n) doesn't add terminator anymore (fixes #1545) --- CHANGELOG.md | 2 ++ extras/tests/JsonSerializer/JsonObject.cpp | 7 +++++-- extras/tests/Misc/StringWriter.cpp | 6 +++--- .../MsgPackSerializer/destination_types.cpp | 18 +++++++++++++++--- extras/tests/TextFormatter/writeInteger.cpp | 2 +- extras/tests/TextFormatter/writeString.cpp | 2 +- src/ArduinoJson/Json/JsonSerializer.hpp | 2 ++ src/ArduinoJson/Json/PrettyJsonSerializer.hpp | 2 +- src/ArduinoJson/MsgPack/MsgPackSerializer.hpp | 2 ++ .../Writers/StaticStringWriter.hpp | 7 +------ src/ArduinoJson/Serialization/serialize.hpp | 17 ++++++++++++++--- 11 files changed, 47 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c787e9cf..67756434 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ HEAD * Simplified `JsonVariant::as()` to always return `T` (see below) * Updated folders list in `.mbedignore` (PR #1515 by @AGlass0fMilk) * Fixed member-call-on-null-pointer in `getMember()` when array is empty +* `serializeMsgPack(doc, buffer, size)` doesn't add null-terminator anymore (issue #1545) +* `serializeJson(doc, buffer, size)` adds null-terminator only if there is enough room > ### BREAKING CHANGES > diff --git a/extras/tests/JsonSerializer/JsonObject.cpp b/extras/tests/JsonSerializer/JsonObject.cpp index 2ecea686..a1aa9311 100644 --- a/extras/tests/JsonSerializer/JsonObject.cpp +++ b/extras/tests/JsonSerializer/JsonObject.cpp @@ -8,12 +8,15 @@ static void checkObject(const JsonObject obj, const std::string &expected) { char actual[256]; + memset(actual, '!', sizeof(actual)); + size_t actualLen = serializeJson(obj, actual); size_t measuredLen = measureJson(obj); - REQUIRE(expected == actual); - REQUIRE(expected.size() == actualLen); REQUIRE(expected.size() == measuredLen); + REQUIRE(expected.size() == actualLen); + REQUIRE(actual[actualLen] == 0); // serializeJson() adds a null terminator + REQUIRE(expected == actual); } TEST_CASE("serializeJson(JsonObject)") { diff --git a/extras/tests/Misc/StringWriter.cpp b/extras/tests/Misc/StringWriter.cpp index 1f5609ab..b7f62455 100644 --- a/extras/tests/Misc/StringWriter.cpp +++ b/extras/tests/Misc/StringWriter.cpp @@ -39,15 +39,15 @@ void common_tests(StringWriter& sb, const String& output) { } TEST_CASE("StaticStringWriter") { - char output[20]; + char output[20] = {0}; StaticStringWriter sb(output, sizeof(output)); common_tests(sb, static_cast(output)); SECTION("OverCapacity") { - REQUIRE(19 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); + REQUIRE(20 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")); REQUIRE(0 == print(sb, "ABC")); - REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output); + REQUIRE("ABCDEFGHIJKLMNOPQRST" == std::string(output, 20)); } } diff --git a/extras/tests/MsgPackSerializer/destination_types.cpp b/extras/tests/MsgPackSerializer/destination_types.cpp index e56d3f75..7923800e 100644 --- a/extras/tests/MsgPackSerializer/destination_types.cpp +++ b/extras/tests/MsgPackSerializer/destination_types.cpp @@ -29,19 +29,31 @@ TEST_CASE("serialize MsgPack to various destination types") { REQUIRE(expected_length == len); } */ - SECTION("char[]") { + SECTION("char[] larger than needed") { char result[64]; + memset(result, 42, sizeof(result)); size_t len = serializeMsgPack(object, result); - REQUIRE(std::string(expected_result) == result); REQUIRE(expected_length == len); + REQUIRE(std::string(expected_result, len) == std::string(result, len)); + REQUIRE(result[len] == 42); + } + + SECTION("char[] of the right size") { // #1545 + char result[13]; + size_t len = serializeMsgPack(object, result); + + REQUIRE(expected_length == len); + REQUIRE(std::string(expected_result, len) == std::string(result, len)); } SECTION("char*") { char result[64]; + memset(result, 42, sizeof(result)); size_t len = serializeMsgPack(object, result, 64); - REQUIRE(std::string(expected_result) == result); REQUIRE(expected_length == len); + REQUIRE(std::string(expected_result, len) == std::string(result, len)); + REQUIRE(result[len] == 42); } } diff --git a/extras/tests/TextFormatter/writeInteger.cpp b/extras/tests/TextFormatter/writeInteger.cpp index 6e9d9fac..37fa446b 100644 --- a/extras/tests/TextFormatter/writeInteger.cpp +++ b/extras/tests/TextFormatter/writeInteger.cpp @@ -13,7 +13,7 @@ using namespace ARDUINOJSON_NAMESPACE; template void checkWriteInteger(T value, std::string expected) { - char output[1024]; + char output[64] = {0}; StaticStringWriter sb(output, sizeof(output)); TextFormatter writer(sb); writer.writeInteger(value); diff --git a/extras/tests/TextFormatter/writeString.cpp b/extras/tests/TextFormatter/writeString.cpp index 7471d3ad..eccc4b4d 100644 --- a/extras/tests/TextFormatter/writeString.cpp +++ b/extras/tests/TextFormatter/writeString.cpp @@ -10,7 +10,7 @@ using namespace ARDUINOJSON_NAMESPACE; void check(const char* input, std::string expected) { - char output[1024]; + char output[64] = {0}; StaticStringWriter sb(output, sizeof(output)); TextFormatter writer(sb); writer.writeString(input); diff --git a/src/ArduinoJson/Json/JsonSerializer.hpp b/src/ArduinoJson/Json/JsonSerializer.hpp index 220aa117..5cb9aa27 100644 --- a/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/JsonSerializer.hpp @@ -14,6 +14,8 @@ namespace ARDUINOJSON_NAMESPACE { template class JsonSerializer : public Visitor { public: + static const bool producesText = true; + JsonSerializer(TWriter writer) : _formatter(writer) {} FORCE_INLINE size_t visitArray(const CollectionData &array) { diff --git a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp index d3b8d009..dbb0c172 100644 --- a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp +++ b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp @@ -16,7 +16,7 @@ class PrettyJsonSerializer : public JsonSerializer { typedef JsonSerializer base; public: - PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} + PrettyJsonSerializer(TWriter writer) : base(writer), _nesting(0) {} size_t visitArray(const CollectionData &array) { VariantSlot *slot = array.head(); diff --git a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp index ca1424b9..b1cd8727 100644 --- a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp @@ -17,6 +17,8 @@ namespace ARDUINOJSON_NAMESPACE { template class MsgPackSerializer : public Visitor { public: + static const bool producesText = false; + MsgPackSerializer(TWriter writer) : _writer(writer) {} template diff --git a/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp b/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp index f5ceac19..1a4213b8 100644 --- a/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp +++ b/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp @@ -8,18 +8,14 @@ namespace ARDUINOJSON_NAMESPACE { -// A Print implementation that allows to write in a char[] class StaticStringWriter { public: - StaticStringWriter(char *buf, size_t size) : end(buf + size - 1), p(buf) { - *p = '\0'; - } + StaticStringWriter(char *buf, size_t size) : end(buf + size), p(buf) {} size_t write(uint8_t c) { if (p >= end) return 0; *p++ = static_cast(c); - *p = '\0'; return 1; } @@ -29,7 +25,6 @@ class StaticStringWriter { *p++ = static_cast(*s++); n--; } - *p = '\0'; return size_t(p - begin); } diff --git a/src/ArduinoJson/Serialization/serialize.hpp b/src/ArduinoJson/Serialization/serialize.hpp index 3aabc49e..16d2e4ef 100644 --- a/src/ArduinoJson/Serialization/serialize.hpp +++ b/src/ArduinoJson/Serialization/serialize.hpp @@ -23,11 +23,23 @@ size_t serialize(const TSource &source, TDestination &destination) { } template