Skip to content

Commit e6b192a

Browse files
authored
Merge pull request Tencent#869 from StilesCrisis/writer-key-fix
Writer EndObject missing-value fix
2 parents 9cabd63 + fa84cd1 commit e6b192a

File tree

4 files changed

+80
-4
lines changed

4 files changed

+80
-4
lines changed

include/rapidjson/prettywriter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,10 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
136136

137137
bool EndObject(SizeType memberCount = 0) {
138138
(void)memberCount;
139-
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
140-
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
139+
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
140+
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
141+
RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
142+
141143
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
142144

143145
if (!empty) {

include/rapidjson/writer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,9 @@ class Writer {
221221

222222
bool EndObject(SizeType memberCount = 0) {
223223
(void)memberCount;
224-
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
225-
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
224+
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
225+
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object
226+
RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value
226227
level_stack_.template Pop<Level>(1);
227228
return EndValue(WriteEndObject());
228229
}

test/unittest/prettywritertest.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,57 @@ TEST(PrettyWriter, RawValue) {
207207
buffer.GetString());
208208
}
209209

210+
TEST(PrettyWriter, InvalidEventSequence) {
211+
// {]
212+
{
213+
StringBuffer buffer;
214+
PrettyWriter<StringBuffer> writer(buffer);
215+
writer.StartObject();
216+
EXPECT_THROW(writer.EndArray(), AssertException);
217+
EXPECT_FALSE(writer.IsComplete());
218+
}
219+
220+
// [}
221+
{
222+
StringBuffer buffer;
223+
PrettyWriter<StringBuffer> writer(buffer);
224+
writer.StartArray();
225+
EXPECT_THROW(writer.EndObject(), AssertException);
226+
EXPECT_FALSE(writer.IsComplete());
227+
}
228+
229+
// { 1:
230+
{
231+
StringBuffer buffer;
232+
PrettyWriter<StringBuffer> writer(buffer);
233+
writer.StartObject();
234+
EXPECT_THROW(writer.Int(1), AssertException);
235+
EXPECT_FALSE(writer.IsComplete());
236+
}
237+
238+
// { 'a' }
239+
{
240+
StringBuffer buffer;
241+
PrettyWriter<StringBuffer> writer(buffer);
242+
writer.StartObject();
243+
writer.Key("a");
244+
EXPECT_THROW(writer.EndObject(), AssertException);
245+
EXPECT_FALSE(writer.IsComplete());
246+
}
247+
248+
// { 'a':'b','c' }
249+
{
250+
StringBuffer buffer;
251+
PrettyWriter<StringBuffer> writer(buffer);
252+
writer.StartObject();
253+
writer.Key("a");
254+
writer.String("b");
255+
writer.Key("c");
256+
EXPECT_THROW(writer.EndObject(), AssertException);
257+
EXPECT_FALSE(writer.IsComplete());
258+
}
259+
}
260+
210261
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
211262

212263
static PrettyWriter<StringBuffer> WriterGen(StringBuffer &target) {

test/unittest/writertest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,28 @@ TEST(Writer, InvalidEventSequence) {
442442
EXPECT_THROW(writer.Int(1), AssertException);
443443
EXPECT_FALSE(writer.IsComplete());
444444
}
445+
446+
// { 'a' }
447+
{
448+
StringBuffer buffer;
449+
Writer<StringBuffer> writer(buffer);
450+
writer.StartObject();
451+
writer.Key("a");
452+
EXPECT_THROW(writer.EndObject(), AssertException);
453+
EXPECT_FALSE(writer.IsComplete());
454+
}
455+
456+
// { 'a':'b','c' }
457+
{
458+
StringBuffer buffer;
459+
Writer<StringBuffer> writer(buffer);
460+
writer.StartObject();
461+
writer.Key("a");
462+
writer.String("b");
463+
writer.Key("c");
464+
EXPECT_THROW(writer.EndObject(), AssertException);
465+
EXPECT_FALSE(writer.IsComplete());
466+
}
445467
}
446468

447469
TEST(Writer, NaN) {

0 commit comments

Comments
 (0)