diff options
author | Milo Yip <miloyip@gmail.com> | 2018-02-13 05:58:41 +0300 |
---|---|---|
committer | Milo Yip <miloyip@gmail.com> | 2018-02-13 05:58:41 +0300 |
commit | 966987625c4e8f9bc5adce73b9557be128c27be8 (patch) | |
tree | bd39ad73a818fab086a1a39d0f07f57f2546431a | |
parent | e2d0437a9cd6f73612b155bd4e4150c66a64c678 (diff) |
Add transcoding/validation to Writer::RawValue()issue1153_rawvalueencoding
Fix #1152
-rw-r--r-- | include/rapidjson/writer.h | 11 | ||||
-rw-r--r-- | 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 e610ebb6..a9788915 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<SourceEncoding> is(json); + while (RAPIDJSON_LIKELY(is.Tell() < length)) { + const Ch c = is.Peek(); + RAPIDJSON_ASSERT(c != '\0'); + if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) : + Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_)))) + return false; } return true; } diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index b190c6c2..232b03d1 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<UTF32<> > sb; + Writer<GenericStringBuffer<UTF32<> >, UTF8<>, UTF32<> > writer(sb); + writer.RawValue("null", 4, kNullType); + EXPECT_TRUE(writer.IsComplete()); + const unsigned *out = sb.GetString(); + EXPECT_EQ(static_cast<unsigned>('n'), out[0]); + EXPECT_EQ(static_cast<unsigned>('u'), out[1]); + EXPECT_EQ(static_cast<unsigned>('l'), out[2]); + EXPECT_EQ(static_cast<unsigned>('l'), out[3]); + EXPECT_EQ(static_cast<unsigned>(0 ), out[4]); + } + + { + GenericStringBuffer<UTF8<> > sb; + Writer<GenericStringBuffer<UTF8<> >, UTF16<>, UTF8<> > writer(sb); + writer.RawValue(L"null", 4, kNullType); + EXPECT_TRUE(writer.IsComplete()); + EXPECT_STREQ("null", sb.GetString()); + } + + { + // Fail in transcoding + GenericStringBuffer<UTF16<> > buffer; + Writer<GenericStringBuffer<UTF16<> >, UTF8<>, UTF16<> > writer(buffer); + EXPECT_FALSE(writer.RawValue("\"\xfe\"", 3, kStringType)); + } + + { + // Fail in encoding validation + StringBuffer buffer; + Writer<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer); + EXPECT_FALSE(writer.RawValue("\"\xfe\"", 3, kStringType)); + } +} + #if RAPIDJSON_HAS_CXX11_RVALUE_REFS static Writer<StringBuffer> WriterGen(StringBuffer &target) { Writer<StringBuffer> writer(target); |