From 11defb7aa4fd20c58f4ce2836801e23fca68a08d Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Fri, 3 Aug 2018 12:17:29 +0200 Subject: [PATCH 1/3] Wrap all WriteXxx() calls within EndValue(), to ensure a flush after root-level scalar value This attempts to fix issue #1336. --- include/rapidjson/prettywriter.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/rapidjson/prettywriter.h b/include/rapidjson/prettywriter.h index 95bb6ff..45afb69 100644 --- a/include/rapidjson/prettywriter.h +++ b/include/rapidjson/prettywriter.h @@ -92,26 +92,26 @@ public: */ //@{ - bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } - bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } - bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } - bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } - bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } - bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } - bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); } bool RawNumber(const Ch* str, SizeType length, bool copy = false) { RAPIDJSON_ASSERT(str != 0); (void)copy; PrettyPrefix(kNumberType); - return Base::WriteString(str, length); + return Base::EndValue(Base::WriteString(str, length)); } bool String(const Ch* str, SizeType length, bool copy = false) { RAPIDJSON_ASSERT(str != 0); (void)copy; PrettyPrefix(kStringType); - return Base::WriteString(str, length); + return Base::EndValue(Base::WriteString(str, length)); } #if RAPIDJSON_HAS_STDSTRING @@ -146,7 +146,7 @@ public: Base::os_->Put('\n'); WriteIndent(); } - bool ret = Base::WriteEndObject(); + bool ret = Base::EndValue(Base::WriteEndObject()); (void)ret; RAPIDJSON_ASSERT(ret == true); if (Base::level_stack_.Empty()) // end of json text @@ -170,7 +170,7 @@ public: Base::os_->Put('\n'); WriteIndent(); } - bool ret = Base::WriteEndArray(); + bool ret = Base::EndValue(Base::WriteEndArray()); (void)ret; RAPIDJSON_ASSERT(ret == true); if (Base::level_stack_.Empty()) // end of json text @@ -201,7 +201,7 @@ public: bool RawValue(const Ch* json, size_t length, Type type) { RAPIDJSON_ASSERT(json != 0); PrettyPrefix(type); - return Base::WriteRawValue(json, length); + return Base::EndValue(Base::WriteRawValue(json, length)); } protected: From 3fc9299b84692feae48892293da20b482157520f Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Fri, 3 Aug 2018 12:34:03 +0200 Subject: [PATCH 2/3] Add simple test for issue #1336 --- test/unittest/prettywritertest.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/unittest/prettywritertest.cpp b/test/unittest/prettywritertest.cpp index 43617a2..c14ea46 100644 --- a/test/unittest/prettywritertest.cpp +++ b/test/unittest/prettywritertest.cpp @@ -339,6 +339,17 @@ TEST(PrettyWriter, MoveCtor) { } #endif +TEST(PrettyWriter, Issue_1336) { + char buf[100] = "Hello"; + + StringBuffer buffer; + PrettyWriter writer(buffer); + writer.String(buf); + + EXPECT_STREQ("\"Hello\"", buffer.GetString()); + EXPECT_TRUE(writer.IsComplete()); \ +} + #ifdef __clang__ RAPIDJSON_DIAG_POP #endif From c9eabf9e13e99e720765f224e97c4cfb6c8a3f2e Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Sun, 5 Aug 2018 09:44:15 +0200 Subject: [PATCH 3/3] Extend the test on issue #1336 to cover all basic types --- test/unittest/prettywritertest.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/test/unittest/prettywritertest.cpp b/test/unittest/prettywritertest.cpp index c14ea46..4bf02bd 100644 --- a/test/unittest/prettywritertest.cpp +++ b/test/unittest/prettywritertest.cpp @@ -340,14 +340,32 @@ TEST(PrettyWriter, MoveCtor) { #endif TEST(PrettyWriter, Issue_1336) { - char buf[100] = "Hello"; +#define T(meth, val, expected) \ + { \ + StringBuffer buffer; \ + PrettyWriter writer(buffer); \ + writer.meth(val); \ + \ + EXPECT_STREQ(expected, buffer.GetString()); \ + EXPECT_TRUE(writer.IsComplete()); \ + } + + T(Bool, false, "false"); + T(Bool, true, "true"); + T(Int, 0, "0"); + T(Uint, 0, "0"); + T(Int64, 0, "0"); + T(Uint64, 0, "0"); + T(Double, 0, "0.0"); + T(String, "Hello", "\"Hello\""); +#undef T StringBuffer buffer; PrettyWriter writer(buffer); - writer.String(buf); + writer.Null(); - EXPECT_STREQ("\"Hello\"", buffer.GetString()); - EXPECT_TRUE(writer.IsComplete()); \ + EXPECT_STREQ("null", buffer.GetString()); + EXPECT_TRUE(writer.IsComplete()); } #ifdef __clang__