From 966987625c4e8f9bc5adce73b9557be128c27be8 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Tue, 13 Feb 2018 10:58:41 +0800 Subject: [PATCH] Add transcoding/validation to Writer::RawValue() Fix #1152 --- include/rapidjson/writer.h | 11 ++++++++--- test/unittest/writertest.cpp | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index e610ebb..a978891 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -460,9 +460,14 @@ protected: bool WriteRawValue(const Ch* json, size_t length) { PutReserve(*os_, length); - for (size_t i = 0; i < length; i++) { - RAPIDJSON_ASSERT(json[i] != '\0'); - PutUnsafe(*os_, json[i]); + GenericStringStream is(json); + while (RAPIDJSON_LIKELY(is.Tell() < length)) { + const Ch c = is.Peek(); + RAPIDJSON_ASSERT(c != '\0'); + if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; } return true; } diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index b190c6c..232b03d 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -538,6 +538,43 @@ TEST(Writer, RawValue) { EXPECT_STREQ("{\"a\":1,\"raw\":[\"Hello\\nWorld\", 123.456]}", buffer.GetString()); } +TEST(Write, RawValue_Issue1152) { + { + GenericStringBuffer > sb; + Writer >, UTF8<>, UTF32<> > writer(sb); + writer.RawValue("null", 4, kNullType); + EXPECT_TRUE(writer.IsComplete()); + const unsigned *out = sb.GetString(); + EXPECT_EQ(static_cast('n'), out[0]); + EXPECT_EQ(static_cast('u'), out[1]); + EXPECT_EQ(static_cast('l'), out[2]); + EXPECT_EQ(static_cast('l'), out[3]); + EXPECT_EQ(static_cast(0 ), out[4]); + } + + { + GenericStringBuffer > sb; + Writer >, UTF16<>, UTF8<> > writer(sb); + writer.RawValue(L"null", 4, kNullType); + EXPECT_TRUE(writer.IsComplete()); + EXPECT_STREQ("null", sb.GetString()); + } + + { + // Fail in transcoding + GenericStringBuffer > buffer; + Writer >, UTF8<>, UTF16<> > writer(buffer); + EXPECT_FALSE(writer.RawValue("\"\xfe\"", 3, kStringType)); + } + + { + // Fail in encoding validation + StringBuffer buffer; + Writer, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer); + EXPECT_FALSE(writer.RawValue("\"\xfe\"", 3, kStringType)); + } +} + #if RAPIDJSON_HAS_CXX11_RVALUE_REFS static Writer WriterGen(StringBuffer &target) { Writer writer(target);