1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14
15 #include "unittest.h"
16
17 #include "rapidjson/reader.h"
18 #include "rapidjson/internal/dtoa.h"
19 #include "rapidjson/internal/itoa.h"
20 #include "rapidjson/memorystream.h"
21
22 using namespace rapidjson;
23
24 #ifdef __GNUC__
25 RAPIDJSON_DIAG_PUSH
26 RAPIDJSON_DIAG_OFF(effc++)
27 RAPIDJSON_DIAG_OFF(float-equal)
28 #endif
29
30 template<bool expect>
31 struct ParseBoolHandler : BaseReaderHandler<UTF8<>, ParseBoolHandler<expect> > {
ParseBoolHandlerParseBoolHandler32 ParseBoolHandler() : step_(0) {}
DefaultParseBoolHandler33 bool Default() { ADD_FAILURE(); return false; }
34 // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version.
35 // Workaround with EXPECT_TRUE().
BoolParseBoolHandler36 bool Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; return true; }
37
38 unsigned step_;
39 };
40
TEST(Reader,ParseTrue)41 TEST(Reader, ParseTrue) {
42 StringStream s("true");
43 ParseBoolHandler<true> h;
44 Reader reader;
45 reader.Parse(s, h);
46 EXPECT_EQ(1u, h.step_);
47 }
48
TEST(Reader,ParseFalse)49 TEST(Reader, ParseFalse) {
50 StringStream s("false");
51 ParseBoolHandler<false> h;
52 Reader reader;
53 reader.Parse(s, h);
54 EXPECT_EQ(1u, h.step_);
55 }
56
57 struct ParseIntHandler : BaseReaderHandler<UTF8<>, ParseIntHandler> {
ParseIntHandlerParseIntHandler58 ParseIntHandler() : step_(0), actual_() {}
DefaultParseIntHandler59 bool Default() { ADD_FAILURE(); return false; }
IntParseIntHandler60 bool Int(int i) { actual_ = i; step_++; return true; }
61
62 unsigned step_;
63 int actual_;
64 };
65
66 struct ParseUintHandler : BaseReaderHandler<UTF8<>, ParseUintHandler> {
ParseUintHandlerParseUintHandler67 ParseUintHandler() : step_(0), actual_() {}
DefaultParseUintHandler68 bool Default() { ADD_FAILURE(); return false; }
UintParseUintHandler69 bool Uint(unsigned i) { actual_ = i; step_++; return true; }
70
71 unsigned step_;
72 unsigned actual_;
73 };
74
75 struct ParseInt64Handler : BaseReaderHandler<UTF8<>, ParseInt64Handler> {
ParseInt64HandlerParseInt64Handler76 ParseInt64Handler() : step_(0), actual_() {}
DefaultParseInt64Handler77 bool Default() { ADD_FAILURE(); return false; }
Int64ParseInt64Handler78 bool Int64(int64_t i) { actual_ = i; step_++; return true; }
79
80 unsigned step_;
81 int64_t actual_;
82 };
83
84 struct ParseUint64Handler : BaseReaderHandler<UTF8<>, ParseUint64Handler> {
ParseUint64HandlerParseUint64Handler85 ParseUint64Handler() : step_(0), actual_() {}
DefaultParseUint64Handler86 bool Default() { ADD_FAILURE(); return false; }
Uint64ParseUint64Handler87 bool Uint64(uint64_t i) { actual_ = i; step_++; return true; }
88
89 unsigned step_;
90 uint64_t actual_;
91 };
92
93 struct ParseDoubleHandler : BaseReaderHandler<UTF8<>, ParseDoubleHandler> {
ParseDoubleHandlerParseDoubleHandler94 ParseDoubleHandler() : step_(0), actual_() {}
DefaultParseDoubleHandler95 bool Default() { ADD_FAILURE(); return false; }
DoubleParseDoubleHandler96 bool Double(double d) { actual_ = d; step_++; return true; }
97
98 unsigned step_;
99 double actual_;
100 };
101
TEST(Reader,ParseNumber_Integer)102 TEST(Reader, ParseNumber_Integer) {
103 #define TEST_INTEGER(Handler, str, x) \
104 { \
105 StringStream s(str); \
106 Handler h; \
107 Reader reader; \
108 reader.Parse(s, h); \
109 EXPECT_EQ(1u, h.step_); \
110 EXPECT_EQ(x, h.actual_); \
111 }
112
113 TEST_INTEGER(ParseUintHandler, "0", 0u);
114 TEST_INTEGER(ParseUintHandler, "123", 123u);
115 TEST_INTEGER(ParseUintHandler, "2147483648", 2147483648u); // 2^31 - 1 (cannot be stored in int)
116 TEST_INTEGER(ParseUintHandler, "4294967295", 4294967295u);
117
118 TEST_INTEGER(ParseIntHandler, "-123", -123);
119 TEST_INTEGER(ParseIntHandler, "-2147483648", static_cast<int32_t>(0x80000000)); // -2^31 (min of int)
120
121 TEST_INTEGER(ParseUint64Handler, "4294967296", RAPIDJSON_UINT64_C2(1, 0)); // 2^32 (max of unsigned + 1, force to use uint64_t)
122 TEST_INTEGER(ParseUint64Handler, "18446744073709551615", RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)); // 2^64 - 1 (max of uint64_t)
123
124 TEST_INTEGER(ParseInt64Handler, "-2147483649", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x7FFFFFFF))); // -2^31 -1 (min of int - 1, force to use int64_t)
125 TEST_INTEGER(ParseInt64Handler, "-9223372036854775808", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))); // -2^63 (min of int64_t)
126
127 // Random test for uint32_t/int32_t
128 {
129 union {
130 uint32_t u;
131 int32_t i;
132 }u;
133 Random r;
134
135 for (unsigned i = 0; i < 100000; i++) {
136 u.u = r();
137
138 char buffer[32];
139 *internal::u32toa(u.u, buffer) = '\0';
140 TEST_INTEGER(ParseUintHandler, buffer, u.u);
141
142 if (u.i < 0) {
143 *internal::i32toa(u.i, buffer) = '\0';
144 TEST_INTEGER(ParseIntHandler, buffer, u.i);
145 }
146 }
147 }
148
149 // Random test for uint64_t/int64_t
150 {
151 union {
152 uint64_t u;
153 int64_t i;
154 }u;
155 Random r;
156
157 for (unsigned i = 0; i < 100000; i++) {
158 u.u = uint64_t(r()) << 32;
159 u.u |= r();
160
161 char buffer[32];
162 if (u.u >= 4294967296ULL) {
163 *internal::u64toa(u.u, buffer) = '\0';
164 TEST_INTEGER(ParseUint64Handler, buffer, u.u);
165 }
166
167 if (u.i <= -2147483649LL) {
168 *internal::i64toa(u.i, buffer) = '\0';
169 TEST_INTEGER(ParseInt64Handler, buffer, u.i);
170 }
171 }
172 }
173 #undef TEST_INTEGER
174 }
175
176 template<bool fullPrecision>
TestParseDouble()177 static void TestParseDouble() {
178 #define TEST_DOUBLE(fullPrecision, str, x) \
179 { \
180 StringStream s(str); \
181 ParseDoubleHandler h; \
182 Reader reader; \
183 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code()); \
184 EXPECT_EQ(1u, h.step_); \
185 internal::Double e(x), a(h.actual_); \
186 if (fullPrecision) { \
187 EXPECT_EQ(e.Uint64Value(), a.Uint64Value()); \
188 if (e.Uint64Value() != a.Uint64Value()) \
189 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \
190 } \
191 else { \
192 EXPECT_EQ(e.Sign(), a.Sign()); /* for 0.0 != -0.0 */ \
193 EXPECT_DOUBLE_EQ(x, h.actual_); \
194 } \
195 }
196
197 TEST_DOUBLE(fullPrecision, "0.0", 0.0);
198 TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289
199 TEST_DOUBLE(fullPrecision, "1.0", 1.0);
200 TEST_DOUBLE(fullPrecision, "-1.0", -1.0);
201 TEST_DOUBLE(fullPrecision, "1.5", 1.5);
202 TEST_DOUBLE(fullPrecision, "-1.5", -1.5);
203 TEST_DOUBLE(fullPrecision, "3.1416", 3.1416);
204 TEST_DOUBLE(fullPrecision, "1E10", 1E10);
205 TEST_DOUBLE(fullPrecision, "1e10", 1e10);
206 TEST_DOUBLE(fullPrecision, "1E+10", 1E+10);
207 TEST_DOUBLE(fullPrecision, "1E-10", 1E-10);
208 TEST_DOUBLE(fullPrecision, "-1E10", -1E10);
209 TEST_DOUBLE(fullPrecision, "-1e10", -1e10);
210 TEST_DOUBLE(fullPrecision, "-1E+10", -1E+10);
211 TEST_DOUBLE(fullPrecision, "-1E-10", -1E-10);
212 TEST_DOUBLE(fullPrecision, "1.234E+10", 1.234E+10);
213 TEST_DOUBLE(fullPrecision, "1.234E-10", 1.234E-10);
214 TEST_DOUBLE(fullPrecision, "1.79769e+308", 1.79769e+308);
215 TEST_DOUBLE(fullPrecision, "2.22507e-308", 2.22507e-308);
216 TEST_DOUBLE(fullPrecision, "-1.79769e+308", -1.79769e+308);
217 TEST_DOUBLE(fullPrecision, "-2.22507e-308", -2.22507e-308);
218 TEST_DOUBLE(fullPrecision, "4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal
219 TEST_DOUBLE(fullPrecision, "2.2250738585072009e-308", 2.2250738585072009e-308); // Max subnormal double
220 TEST_DOUBLE(fullPrecision, "2.2250738585072014e-308", 2.2250738585072014e-308); // Min normal positive double
221 TEST_DOUBLE(fullPrecision, "1.7976931348623157e+308", 1.7976931348623157e+308); // Max double
222 TEST_DOUBLE(fullPrecision, "1e-10000", 0.0); // must underflow
223 TEST_DOUBLE(fullPrecision, "18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double)
224 TEST_DOUBLE(fullPrecision, "-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double)
225 TEST_DOUBLE(fullPrecision, "0.9868011474609375", 0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120
226 TEST_DOUBLE(fullPrecision, "123e34", 123e34); // Fast Path Cases In Disguise
227 TEST_DOUBLE(fullPrecision, "45913141877270640000.0", 45913141877270640000.0);
228 TEST_DOUBLE(fullPrecision, "2.2250738585072011e-308", 2.2250738585072011e-308); // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
229 TEST_DOUBLE(fullPrecision, "1e-00011111111111", 0.0); // Issue #313
230 TEST_DOUBLE(fullPrecision, "-1e-00011111111111", -0.0);
231 TEST_DOUBLE(fullPrecision, "1e-214748363", 0.0); // Maximum supported negative exponent
232 TEST_DOUBLE(fullPrecision, "1e-214748364", 0.0);
233 TEST_DOUBLE(fullPrecision, "1e-21474836311", 0.0);
234 TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
235
236 // Since
237 // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... �� 10^-324
238 // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... �� 10 ^ -324
239 // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
240 TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
241
242 // More closer to normal/subnormal boundary
243 // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... �� 10^-308
244 TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
245 TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
246
247 // 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
248 // 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
249 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984375", 1.0); // round to even
250 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984374", 0.99999999999999989); // previous double
251 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984376", 1.0); // next double
252 // 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125
253 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203125", 1.0); // round to even
254 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203124", 1.0); // previous double
255 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203126", 1.00000000000000022); // next double
256
257 // Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc
258
259 TEST_DOUBLE(fullPrecision, "72057594037927928.0", 72057594037927928.0);
260 TEST_DOUBLE(fullPrecision, "72057594037927936.0", 72057594037927936.0);
261 TEST_DOUBLE(fullPrecision, "72057594037927932.0", 72057594037927936.0);
262 TEST_DOUBLE(fullPrecision, "7205759403792793199999e-5", 72057594037927928.0);
263 TEST_DOUBLE(fullPrecision, "7205759403792793200001e-5", 72057594037927936.0);
264
265 TEST_DOUBLE(fullPrecision, "9223372036854774784.0", 9223372036854774784.0);
266 TEST_DOUBLE(fullPrecision, "9223372036854775808.0", 9223372036854775808.0);
267 TEST_DOUBLE(fullPrecision, "9223372036854775296.0", 9223372036854775808.0);
268 TEST_DOUBLE(fullPrecision, "922337203685477529599999e-5", 9223372036854774784.0);
269 TEST_DOUBLE(fullPrecision, "922337203685477529600001e-5", 9223372036854775808.0);
270
271 TEST_DOUBLE(fullPrecision, "10141204801825834086073718800384", 10141204801825834086073718800384.0);
272 TEST_DOUBLE(fullPrecision, "10141204801825835211973625643008", 10141204801825835211973625643008.0);
273 TEST_DOUBLE(fullPrecision, "10141204801825834649023672221696", 10141204801825835211973625643008.0);
274 TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169599999e-5", 10141204801825834086073718800384.0);
275 TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169600001e-5", 10141204801825835211973625643008.0);
276
277 TEST_DOUBLE(fullPrecision, "5708990770823838890407843763683279797179383808", 5708990770823838890407843763683279797179383808.0);
278 TEST_DOUBLE(fullPrecision, "5708990770823839524233143877797980545530986496", 5708990770823839524233143877797980545530986496.0);
279 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152", 5708990770823839524233143877797980545530986496.0);
280 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185151999e-3", 5708990770823838890407843763683279797179383808.0);
281 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152001e-3", 5708990770823839524233143877797980545530986496.0);
282
283 {
284 char n1e308[310]; // '1' followed by 308 '0'
285 n1e308[0] = '1';
286 for (int i = 1; i < 309; i++)
287 n1e308[i] = '0';
288 n1e308[309] = '\0';
289 TEST_DOUBLE(fullPrecision, n1e308, 1E308);
290 }
291
292 // Cover trimming
293 TEST_DOUBLE(fullPrecision,
294 "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
295 "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
296 "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
297 "6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
298 "1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
299 "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
300 "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
301 "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
302 "e-308",
303 2.2250738585072014e-308);
304
305 {
306 static const unsigned count = 100; // Tested with 1000000 locally
307 Random r;
308 Reader reader; // Reusing reader to prevent heap allocation
309
310 // Exhaustively test different exponents with random significant
311 for (uint64_t exp = 0; exp < 2047; exp++) {
312 ;
313 for (unsigned i = 0; i < count; i++) {
314 // Need to call r() in two statements for cross-platform coherent sequence.
315 uint64_t u = (exp << 52) | uint64_t(r() & 0x000FFFFF) << 32;
316 u |= uint64_t(r());
317 internal::Double d = internal::Double(u);
318
319 char buffer[32];
320 *internal::dtoa(d.Value(), buffer) = '\0';
321
322 StringStream s(buffer);
323 ParseDoubleHandler h;
324 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
325 EXPECT_EQ(1u, h.step_);
326 internal::Double a(h.actual_);
327 if (fullPrecision) {
328 EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
329 if (d.Uint64Value() != a.Uint64Value())
330 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
331 }
332 else {
333 EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
334 EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
335 }
336 }
337 }
338 }
339
340 // Issue #340
341 TEST_DOUBLE(fullPrecision, "7.450580596923828e-9", 7.450580596923828e-9);
342 {
343 internal::Double d(1.0);
344 for (int i = 0; i < 324; i++) {
345 char buffer[32];
346 *internal::dtoa(d.Value(), buffer) = '\0';
347
348 StringStream s(buffer);
349 ParseDoubleHandler h;
350 Reader reader;
351 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
352 EXPECT_EQ(1u, h.step_);
353 internal::Double a(h.actual_);
354 if (fullPrecision) {
355 EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
356 if (d.Uint64Value() != a.Uint64Value())
357 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
358 }
359 else {
360 EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
361 EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
362 }
363
364
365 d = d.Value() * 0.5;
366 }
367 }
368 #undef TEST_DOUBLE
369 }
370
TEST(Reader,ParseNumber_NormalPrecisionDouble)371 TEST(Reader, ParseNumber_NormalPrecisionDouble) {
372 TestParseDouble<false>();
373 }
374
TEST(Reader,ParseNumber_FullPrecisionDouble)375 TEST(Reader, ParseNumber_FullPrecisionDouble) {
376 TestParseDouble<true>();
377 }
378
TEST(Reader,ParseNumber_NormalPrecisionError)379 TEST(Reader, ParseNumber_NormalPrecisionError) {
380 static unsigned count = 1000000;
381 Random r;
382
383 double ulpSum = 0.0;
384 double ulpMax = 0.0;
385 for (unsigned i = 0; i < count; i++) {
386 internal::Double e, a;
387 do {
388 // Need to call r() in two statements for cross-platform coherent sequence.
389 uint64_t u = uint64_t(r()) << 32;
390 u |= uint64_t(r());
391 e = u;
392 } while (e.IsNan() || e.IsInf() || !e.IsNormal());
393
394 char buffer[32];
395 *internal::dtoa(e.Value(), buffer) = '\0';
396
397 StringStream s(buffer);
398 ParseDoubleHandler h;
399 Reader reader;
400 ASSERT_EQ(kParseErrorNone, reader.Parse(s, h).Code());
401 EXPECT_EQ(1u, h.step_);
402
403 a = h.actual_;
404 uint64_t bias1 = e.ToBias();
405 uint64_t bias2 = a.ToBias();
406 double ulp = bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1;
407 ulpMax = std::max(ulpMax, ulp);
408 ulpSum += ulp;
409 }
410 printf("ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax);
411 }
412
TEST(Reader,ParseNumber_Error)413 TEST(Reader, ParseNumber_Error) {
414 #define TEST_NUMBER_ERROR(errorCode, str) \
415 { \
416 char buffer[1001]; \
417 sprintf(buffer, "%s", str); \
418 InsituStringStream s(buffer); \
419 BaseReaderHandler<> h; \
420 Reader reader; \
421 EXPECT_FALSE(reader.Parse(s, h)); \
422 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
423 }
424
425 // Number too big to be stored in double.
426 {
427 char n1e309[311]; // '1' followed by 309 '0'
428 n1e309[0] = '1';
429 for (int i = 1; i < 310; i++)
430 n1e309[i] = '0';
431 n1e309[310] = '\0';
432 TEST_NUMBER_ERROR(kParseErrorNumberTooBig, n1e309);
433 }
434 TEST_NUMBER_ERROR(kParseErrorNumberTooBig, "1e309");
435
436 // Miss fraction part in number.
437 TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.");
438 TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.a");
439
440 // Miss exponent in number.
441 TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e");
442 TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e_");
443
444 #undef TEST_NUMBER_ERROR
445 }
446
447 template <typename Encoding>
448 struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encoding> > {
ParseStringHandlerParseStringHandler449 ParseStringHandler() : str_(0), length_(0), copy_() {}
~ParseStringHandlerParseStringHandler450 ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
451
452 ParseStringHandler(const ParseStringHandler&);
453 ParseStringHandler& operator=(const ParseStringHandler&);
454
DefaultParseStringHandler455 bool Default() { ADD_FAILURE(); return false; }
StringParseStringHandler456 bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
457 EXPECT_EQ(0, str_);
458 if (copy) {
459 str_ = (typename Encoding::Ch*)malloc((length + 1) * sizeof(typename Encoding::Ch));
460 memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
461 }
462 else
463 str_ = str;
464 length_ = length;
465 copy_ = copy;
466 return true;
467 }
468
469 const typename Encoding::Ch* str_;
470 size_t length_;
471 bool copy_;
472 };
473
TEST(Reader,ParseString)474 TEST(Reader, ParseString) {
475 #define TEST_STRING(Encoding, e, x) \
476 { \
477 Encoding::Ch* buffer = StrDup(x); \
478 GenericInsituStringStream<Encoding> is(buffer); \
479 ParseStringHandler<Encoding> h; \
480 GenericReader<Encoding, Encoding> reader; \
481 reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(is, h); \
482 EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h.str_)); \
483 EXPECT_EQ(StrLen(e), h.length_); \
484 free(buffer); \
485 GenericStringStream<Encoding> s(x); \
486 ParseStringHandler<Encoding> h2; \
487 GenericReader<Encoding, Encoding> reader2; \
488 reader2.Parse(s, h2); \
489 EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h2.str_)); \
490 EXPECT_EQ(StrLen(e), h2.length_); \
491 }
492
493 // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
494 // And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
495 // In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
496 // Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
497 #define ARRAY(...) { __VA_ARGS__ }
498 #define TEST_STRINGARRAY(Encoding, utype, array, x) \
499 { \
500 static const utype ue[] = array; \
501 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
502 TEST_STRING(Encoding, e, x); \
503 }
504
505 #define TEST_STRINGARRAY2(Encoding, utype, earray, xarray) \
506 { \
507 static const utype ue[] = earray; \
508 static const utype xe[] = xarray; \
509 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
510 static const Encoding::Ch* x = reinterpret_cast<const Encoding::Ch *>(&xe[0]); \
511 TEST_STRING(Encoding, e, x); \
512 }
513
514 TEST_STRING(UTF8<>, "", "\"\"");
515 TEST_STRING(UTF8<>, "Hello", "\"Hello\"");
516 TEST_STRING(UTF8<>, "Hello\nWorld", "\"Hello\\nWorld\"");
517 TEST_STRING(UTF8<>, "\"\\/\b\f\n\r\t", "\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
518 TEST_STRING(UTF8<>, "\x24", "\"\\u0024\""); // Dollar sign U+0024
519 TEST_STRING(UTF8<>, "\xC2\xA2", "\"\\u00A2\""); // Cents sign U+00A2
520 TEST_STRING(UTF8<>, "\xE2\x82\xAC", "\"\\u20AC\""); // Euro sign U+20AC
521 TEST_STRING(UTF8<>, "\xF0\x9D\x84\x9E", "\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
522
523 // UTF16
524 TEST_STRING(UTF16<>, L"", L"\"\"");
525 TEST_STRING(UTF16<>, L"Hello", L"\"Hello\"");
526 TEST_STRING(UTF16<>, L"Hello\nWorld", L"\"Hello\\nWorld\"");
527 TEST_STRING(UTF16<>, L"\"\\/\b\f\n\r\t", L"\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
528 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x0024, 0x0000), L"\"\\u0024\"");
529 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x00A2, 0x0000), L"\"\\u00A2\""); // Cents sign U+00A2
530 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x20AC, 0x0000), L"\"\\u20AC\""); // Euro sign U+20AC
531 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0xD834, 0xDD1E, 0x0000), L"\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
532
533 // UTF32
534 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\0'), ARRAY('\"', '\"', '\0'));
535 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\"', '\0'));
536 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\n', 'W', 'o', 'r', 'l', 'd', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\\', 'n', 'W', 'o', 'r', 'l', 'd', '\"', '\0'));
537 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\"', '\\', '/', '\b', '\f', '\n', '\r', '\t', '\0'), ARRAY('\"', '\\', '\"', '\\', '\\', '/', '\\', 'b', '\\', 'f', '\\', 'n', '\\', 'r', '\\', 't', '\"', '\0'));
538 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x00024, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', '2', '4', '\"', '\0'));
539 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x000A2, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', 'A', '2', '\"', '\0')); // Cents sign U+00A2
540 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x020AC, 0x0000), ARRAY('\"', '\\', 'u', '2', '0', 'A', 'C', '\"', '\0')); // Euro sign U+20AC
541 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x1D11E, 0x0000), ARRAY('\"', '\\', 'u', 'D', '8', '3', '4', '\\', 'u', 'D', 'D', '1', 'E', '\"', '\0')); // G clef sign U+1D11E
542
543 #undef TEST_STRINGARRAY
544 #undef ARRAY
545 #undef TEST_STRING
546
547 // Support of null character in string
548 {
549 StringStream s("\"Hello\\u0000World\"");
550 const char e[] = "Hello\0World";
551 ParseStringHandler<UTF8<> > h;
552 Reader reader;
553 reader.Parse(s, h);
554 EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1));
555 EXPECT_EQ(11u, h.length_);
556 }
557 }
558
TEST(Reader,ParseString_Transcoding)559 TEST(Reader, ParseString_Transcoding) {
560 const char* x = "\"Hello\"";
561 const wchar_t* e = L"Hello";
562 GenericStringStream<UTF8<> > is(x);
563 GenericReader<UTF8<>, UTF16<> > reader;
564 ParseStringHandler<UTF16<> > h;
565 reader.Parse(is, h);
566 EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
567 EXPECT_EQ(StrLen(e), h.length_);
568 }
569
TEST(Reader,ParseString_TranscodingWithValidation)570 TEST(Reader, ParseString_TranscodingWithValidation) {
571 const char* x = "\"Hello\"";
572 const wchar_t* e = L"Hello";
573 GenericStringStream<UTF8<> > is(x);
574 GenericReader<UTF8<>, UTF16<> > reader;
575 ParseStringHandler<UTF16<> > h;
576 reader.Parse<kParseValidateEncodingFlag>(is, h);
577 EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
578 EXPECT_EQ(StrLen(e), h.length_);
579 }
580
TEST(Reader,ParseString_NonDestructive)581 TEST(Reader, ParseString_NonDestructive) {
582 StringStream s("\"Hello\\nWorld\"");
583 ParseStringHandler<UTF8<> > h;
584 Reader reader;
585 reader.Parse(s, h);
586 EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_));
587 EXPECT_EQ(11u, h.length_);
588 }
589
590 template <typename Encoding>
TestString(const typename Encoding::Ch * str)591 ParseErrorCode TestString(const typename Encoding::Ch* str) {
592 GenericStringStream<Encoding> s(str);
593 BaseReaderHandler<Encoding> h;
594 GenericReader<Encoding, Encoding> reader;
595 reader.template Parse<kParseValidateEncodingFlag>(s, h);
596 return reader.GetParseErrorCode();
597 }
598
TEST(Reader,ParseString_Error)599 TEST(Reader, ParseString_Error) {
600 #define TEST_STRING_ERROR(errorCode, str)\
601 EXPECT_EQ(errorCode, TestString<UTF8<> >(str))
602
603 #define ARRAY(...) { __VA_ARGS__ }
604 #define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array) \
605 { \
606 static const utype ue[] = array; \
607 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
608 EXPECT_EQ(kParseErrorStringInvalidEncoding, TestString<Encoding>(e));\
609 /* decode error */\
610 GenericStringStream<Encoding> s(e);\
611 BaseReaderHandler<TargetEncoding> h;\
612 GenericReader<Encoding, TargetEncoding> reader;\
613 reader.Parse(s, h);\
614 EXPECT_EQ(kParseErrorStringInvalidEncoding, reader.GetParseErrorCode());\
615 }
616
617 // Invalid escape character in string.
618 TEST_STRING_ERROR(kParseErrorStringEscapeInvalid, "[\"\\a\"]");
619
620 // Incorrect hex digit after \\u escape in string.
621 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uABCG\"]");
622
623 // Quotation in \\u escape in string (Issue #288)
624 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uaaa\"]");
625 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uD800\\uFFF\"]");
626
627 // The surrogate pair in string is invalid.
628 TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800X\"]");
629 TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800\\uFFFF\"]");
630
631 // Missing a closing quotation mark in string.
632 TEST_STRING_ERROR(kParseErrorStringMissQuotationMark, "[\"Test]");
633
634 // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
635
636 // 3 Malformed sequences
637
638 // 3.1 Unexpected continuation bytes
639 {
640 char e[] = { '[', '\"', 0, '\"', ']', '\0' };
641 for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
642 e[2] = c;
643 ParseErrorCode error = TestString<UTF8<> >(e);
644 EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
645 if (error != kParseErrorStringInvalidEncoding)
646 std::cout << (unsigned)(unsigned char)c << std::endl;
647 }
648 }
649
650 // 3.2 Lonely start characters, 3.5 Impossible bytes
651 {
652 char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
653 for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
654 e[2] = (char)c;
655 TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e);
656 }
657 }
658
659 // 4 Overlong sequences
660
661 // 4.1 Examples of an overlong ASCII character
662 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0'));
663 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0'));
664 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0'));
665
666 // 4.2 Maximum overlong sequences
667 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0'));
668 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0'));
669 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0'));
670
671 // 4.3 Overlong representation of the NUL character
672 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0'));
673 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0'));
674 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0'));
675
676 // 5 Illegal code positions
677
678 // 5.1 Single UTF-16 surrogates
679 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xA0u, 0x80u, '\"', ']', '\0'));
680 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xADu, 0xBFu, '\"', ']', '\0'));
681 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAEu, 0x80u, '\"', ']', '\0'));
682 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAFu, 0xBFu, '\"', ']', '\0'));
683 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xB0u, 0x80u, '\"', ']', '\0'));
684 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBEu, 0x80u, '\"', ']', '\0'));
685 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBFu, 0xBFu, '\"', ']', '\0'));
686
687 // Malform UTF-16 sequences
688 TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xDC00, 0xDC00, '\"', ']', '\0'));
689 TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xD800, 0xD800, '\"', ']', '\0'));
690
691 // Malform UTF-32 sequence
692 TEST_STRINGENCODING_ERROR(UTF32<>, UTF8<>, unsigned, ARRAY('[', '\"', 0x110000, '\"', ']', '\0'));
693
694 // Malform ASCII sequence
695 TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x80), '\"', ']', '\0'));
696
697 #undef ARRAY
698 #undef TEST_STRINGARRAY_ERROR
699 }
700
701 template <unsigned count>
702 struct ParseArrayHandler : BaseReaderHandler<UTF8<>, ParseArrayHandler<count> > {
ParseArrayHandlerParseArrayHandler703 ParseArrayHandler() : step_(0) {}
704
DefaultParseArrayHandler705 bool Default() { ADD_FAILURE(); return false; }
UintParseArrayHandler706 bool Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; return true; }
StartArrayParseArrayHandler707 bool StartArray() { EXPECT_EQ(0u, step_); step_++; return true; }
EndArrayParseArrayHandler708 bool EndArray(SizeType) { step_++; return true; }
709
710 unsigned step_;
711 };
712
TEST(Reader,ParseEmptyArray)713 TEST(Reader, ParseEmptyArray) {
714 char *json = StrDup("[ ] ");
715 InsituStringStream s(json);
716 ParseArrayHandler<0> h;
717 Reader reader;
718 reader.Parse(s, h);
719 EXPECT_EQ(2u, h.step_);
720 free(json);
721 }
722
TEST(Reader,ParseArray)723 TEST(Reader, ParseArray) {
724 char *json = StrDup("[1, 2, 3, 4]");
725 InsituStringStream s(json);
726 ParseArrayHandler<4> h;
727 Reader reader;
728 reader.Parse(s, h);
729 EXPECT_EQ(6u, h.step_);
730 free(json);
731 }
732
TEST(Reader,ParseArray_Error)733 TEST(Reader, ParseArray_Error) {
734 #define TEST_ARRAY_ERROR(errorCode, str) \
735 { \
736 char buffer[1001]; \
737 strncpy(buffer, str, 1000); \
738 InsituStringStream s(buffer); \
739 BaseReaderHandler<> h; \
740 GenericReader<UTF8<>, UTF8<>, CrtAllocator> reader; \
741 EXPECT_FALSE(reader.Parse(s, h)); \
742 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
743 }
744
745 // Missing a comma or ']' after an array element.
746 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1");
747 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1}");
748 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1 2]");
749
750 #undef TEST_ARRAY_ERROR
751 }
752
753 struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
ParseObjectHandlerParseObjectHandler754 ParseObjectHandler() : step_(0) {}
755
DefaultParseObjectHandler756 bool Default() { ADD_FAILURE(); return false; }
NullParseObjectHandler757 bool Null() { EXPECT_EQ(8u, step_); step_++; return true; }
BoolParseObjectHandler758 bool Bool(bool b) {
759 switch(step_) {
760 case 4: EXPECT_TRUE(b); step_++; return true;
761 case 6: EXPECT_FALSE(b); step_++; return true;
762 default: ADD_FAILURE(); return false;
763 }
764 }
IntParseObjectHandler765 bool Int(int i) {
766 switch(step_) {
767 case 10: EXPECT_EQ(123, i); step_++; return true;
768 case 15: EXPECT_EQ(1, i); step_++; return true;
769 case 16: EXPECT_EQ(2, i); step_++; return true;
770 case 17: EXPECT_EQ(3, i); step_++; return true;
771 default: ADD_FAILURE(); return false;
772 }
773 }
UintParseObjectHandler774 bool Uint(unsigned i) { return Int(i); }
DoubleParseObjectHandler775 bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
StringParseObjectHandler776 bool String(const char* str, size_t, bool) {
777 switch(step_) {
778 case 1: EXPECT_STREQ("hello", str); step_++; return true;
779 case 2: EXPECT_STREQ("world", str); step_++; return true;
780 case 3: EXPECT_STREQ("t", str); step_++; return true;
781 case 5: EXPECT_STREQ("f", str); step_++; return true;
782 case 7: EXPECT_STREQ("n", str); step_++; return true;
783 case 9: EXPECT_STREQ("i", str); step_++; return true;
784 case 11: EXPECT_STREQ("pi", str); step_++; return true;
785 case 13: EXPECT_STREQ("a", str); step_++; return true;
786 default: ADD_FAILURE(); return false;
787 }
788 }
StartObjectParseObjectHandler789 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
EndObjectParseObjectHandler790 bool EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++; return true; }
StartArrayParseObjectHandler791 bool StartArray() { EXPECT_EQ(14u, step_); step_++; return true; }
EndArrayParseObjectHandler792 bool EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++; return true; }
793
794 unsigned step_;
795 };
796
TEST(Reader,ParseObject)797 TEST(Reader, ParseObject) {
798 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
799
800 // Insitu
801 {
802 char* json2 = StrDup(json);
803 InsituStringStream s(json2);
804 ParseObjectHandler h;
805 Reader reader;
806 reader.Parse<kParseInsituFlag>(s, h);
807 EXPECT_EQ(20u, h.step_);
808 free(json2);
809 }
810
811 // Normal
812 {
813 StringStream s(json);
814 ParseObjectHandler h;
815 Reader reader;
816 reader.Parse(s, h);
817 EXPECT_EQ(20u, h.step_);
818 }
819 }
820
821 struct ParseEmptyObjectHandler : BaseReaderHandler<UTF8<>, ParseEmptyObjectHandler> {
ParseEmptyObjectHandlerParseEmptyObjectHandler822 ParseEmptyObjectHandler() : step_(0) {}
823
DefaultParseEmptyObjectHandler824 bool Default() { ADD_FAILURE(); return false; }
StartObjectParseEmptyObjectHandler825 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
EndObjectParseEmptyObjectHandler826 bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
827
828 unsigned step_;
829 };
830
TEST(Reader,Parse_EmptyObject)831 TEST(Reader, Parse_EmptyObject) {
832 StringStream s("{ } ");
833 ParseEmptyObjectHandler h;
834 Reader reader;
835 reader.Parse(s, h);
836 EXPECT_EQ(2u, h.step_);
837 }
838
839 struct ParseMultipleRootHandler : BaseReaderHandler<UTF8<>, ParseMultipleRootHandler> {
ParseMultipleRootHandlerParseMultipleRootHandler840 ParseMultipleRootHandler() : step_(0) {}
841
DefaultParseMultipleRootHandler842 bool Default() { ADD_FAILURE(); return false; }
StartObjectParseMultipleRootHandler843 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
EndObjectParseMultipleRootHandler844 bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
StartArrayParseMultipleRootHandler845 bool StartArray() { EXPECT_EQ(2u, step_); step_++; return true; }
EndArrayParseMultipleRootHandler846 bool EndArray(SizeType) { EXPECT_EQ(3u, step_); step_++; return true; }
847
848 unsigned step_;
849 };
850
851 template <unsigned parseFlags>
TestMultipleRoot()852 void TestMultipleRoot() {
853 StringStream s("{}[] a");
854 ParseMultipleRootHandler h;
855 Reader reader;
856 EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
857 EXPECT_EQ(2u, h.step_);
858 EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
859 EXPECT_EQ(4u, h.step_);
860 EXPECT_EQ(' ', s.Take());
861 EXPECT_EQ('a', s.Take());
862 }
863
TEST(Reader,Parse_MultipleRoot)864 TEST(Reader, Parse_MultipleRoot) {
865 TestMultipleRoot<kParseStopWhenDoneFlag>();
866 }
867
TEST(Reader,ParseIterative_MultipleRoot)868 TEST(Reader, ParseIterative_MultipleRoot) {
869 TestMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
870 }
871
872 template <unsigned parseFlags>
TestInsituMultipleRoot()873 void TestInsituMultipleRoot() {
874 char* buffer = strdup("{}[] a");
875 InsituStringStream s(buffer);
876 ParseMultipleRootHandler h;
877 Reader reader;
878 EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
879 EXPECT_EQ(2u, h.step_);
880 EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
881 EXPECT_EQ(4u, h.step_);
882 EXPECT_EQ(' ', s.Take());
883 EXPECT_EQ('a', s.Take());
884 free(buffer);
885 }
886
TEST(Reader,ParseInsitu_MultipleRoot)887 TEST(Reader, ParseInsitu_MultipleRoot) {
888 TestInsituMultipleRoot<kParseStopWhenDoneFlag>();
889 }
890
TEST(Reader,ParseInsituIterative_MultipleRoot)891 TEST(Reader, ParseInsituIterative_MultipleRoot) {
892 TestInsituMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
893 }
894
895 #define TEST_ERROR(errorCode, str) \
896 { \
897 char buffer[1001]; \
898 strncpy(buffer, str, 1000); \
899 InsituStringStream s(buffer); \
900 BaseReaderHandler<> h; \
901 Reader reader; \
902 EXPECT_FALSE(reader.Parse(s, h)); \
903 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
904 }
905
TEST(Reader,ParseDocument_Error)906 TEST(Reader, ParseDocument_Error) {
907 // The document is empty.
908 TEST_ERROR(kParseErrorDocumentEmpty, "");
909 TEST_ERROR(kParseErrorDocumentEmpty, " ");
910 TEST_ERROR(kParseErrorDocumentEmpty, " \n");
911
912 // The document root must not follow by other values.
913 TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0");
914 TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0");
915 TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []");
916 TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}");
917 }
918
TEST(Reader,ParseValue_Error)919 TEST(Reader, ParseValue_Error) {
920 // Invalid value.
921 TEST_ERROR(kParseErrorValueInvalid, "nulL");
922 TEST_ERROR(kParseErrorValueInvalid, "truE");
923 TEST_ERROR(kParseErrorValueInvalid, "falsE");
924 TEST_ERROR(kParseErrorValueInvalid, "a]");
925 TEST_ERROR(kParseErrorValueInvalid, ".1");
926 }
927
TEST(Reader,ParseObject_Error)928 TEST(Reader, ParseObject_Error) {
929 // Missing a name for object member.
930 TEST_ERROR(kParseErrorObjectMissName, "{1}");
931 TEST_ERROR(kParseErrorObjectMissName, "{:1}");
932 TEST_ERROR(kParseErrorObjectMissName, "{null:1}");
933 TEST_ERROR(kParseErrorObjectMissName, "{true:1}");
934 TEST_ERROR(kParseErrorObjectMissName, "{false:1}");
935 TEST_ERROR(kParseErrorObjectMissName, "{1:1}");
936 TEST_ERROR(kParseErrorObjectMissName, "{[]:1}");
937 TEST_ERROR(kParseErrorObjectMissName, "{{}:1}");
938 TEST_ERROR(kParseErrorObjectMissName, "{xyz:1}");
939
940 // Missing a colon after a name of object member.
941 TEST_ERROR(kParseErrorObjectMissColon, "{\"a\" 1}");
942 TEST_ERROR(kParseErrorObjectMissColon, "{\"a\",1}");
943
944 // Must be a comma or '}' after an object member
945 TEST_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, "{\"a\":1]");
946
947 // This tests that MemoryStream is checking the length in Peek().
948 {
949 MemoryStream ms("{\"a\"", 1);
950 BaseReaderHandler<> h;
951 Reader reader;
952 EXPECT_FALSE(reader.Parse<kParseStopWhenDoneFlag>(ms, h));
953 EXPECT_EQ(kParseErrorObjectMissName, reader.GetParseErrorCode());
954 }
955 }
956
957 #undef TEST_ERROR
958
TEST(Reader,SkipWhitespace)959 TEST(Reader, SkipWhitespace) {
960 StringStream ss(" A \t\tB\n \n\nC\r\r \rD \t\n\r E");
961 const char* expected = "ABCDE";
962 for (size_t i = 0; i < 5; i++) {
963 SkipWhitespace(ss);
964 EXPECT_EQ(expected[i], ss.Take());
965 }
966 }
967
968 // Test implementing a stream without copy stream optimization.
969 // Clone from GenericStringStream except that copy constructor is disabled.
970 template <typename Encoding>
971 class CustomStringStream {
972 public:
973 typedef typename Encoding::Ch Ch;
974
CustomStringStream(const Ch * src)975 CustomStringStream(const Ch *src) : src_(src), head_(src) {}
976
Peek() const977 Ch Peek() const { return *src_; }
Take()978 Ch Take() { return *src_++; }
Tell() const979 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
980
PutBegin()981 Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
Put(Ch)982 void Put(Ch) { RAPIDJSON_ASSERT(false); }
Flush()983 void Flush() { RAPIDJSON_ASSERT(false); }
PutEnd(Ch *)984 size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
985
986 private:
987 // Prohibit copy constructor & assignment operator.
988 CustomStringStream(const CustomStringStream&);
989 CustomStringStream& operator=(const CustomStringStream&);
990
991 const Ch* src_; //!< Current read position.
992 const Ch* head_; //!< Original head of the string.
993 };
994
995 // If the following code is compiled, it should generate compilation error as predicted.
996 // Because CustomStringStream<> is not copyable via making copy constructor private.
997 #if 0
998 namespace rapidjson {
999
1000 template <typename Encoding>
1001 struct StreamTraits<CustomStringStream<Encoding> > {
1002 enum { copyOptimization = 1 };
1003 };
1004
1005 } // namespace rapidjson
1006 #endif
1007
TEST(Reader,CustomStringStream)1008 TEST(Reader, CustomStringStream) {
1009 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
1010 CustomStringStream<UTF8<char> > s(json);
1011 ParseObjectHandler h;
1012 Reader reader;
1013 reader.Parse(s, h);
1014 EXPECT_EQ(20u, h.step_);
1015 }
1016
1017 #include <sstream>
1018
1019 class IStreamWrapper {
1020 public:
1021 typedef char Ch;
1022
IStreamWrapper(std::istream & is)1023 IStreamWrapper(std::istream& is) : is_(is) {}
1024
Peek() const1025 Ch Peek() const {
1026 int c = is_.peek();
1027 return c == std::char_traits<char>::eof() ? '\0' : (Ch)c;
1028 }
1029
Take()1030 Ch Take() {
1031 int c = is_.get();
1032 return c == std::char_traits<char>::eof() ? '\0' : (Ch)c;
1033 }
1034
Tell() const1035 size_t Tell() const { return (size_t)is_.tellg(); }
1036
PutBegin()1037 Ch* PutBegin() { assert(false); return 0; }
Put(Ch)1038 void Put(Ch) { assert(false); }
Flush()1039 void Flush() { assert(false); }
PutEnd(Ch *)1040 size_t PutEnd(Ch*) { assert(false); return 0; }
1041
1042 private:
1043 IStreamWrapper(const IStreamWrapper&);
1044 IStreamWrapper& operator=(const IStreamWrapper&);
1045
1046 std::istream& is_;
1047 };
1048
TEST(Reader,Parse_IStreamWrapper_StringStream)1049 TEST(Reader, Parse_IStreamWrapper_StringStream) {
1050 const char* json = "[1,2,3,4]";
1051
1052 std::stringstream ss(json);
1053 IStreamWrapper is(ss);
1054
1055 Reader reader;
1056 ParseArrayHandler<4> h;
1057 reader.Parse(is, h);
1058 EXPECT_FALSE(reader.HasParseError());
1059 }
1060
1061 // Test iterative parsing.
1062
1063 #define TESTERRORHANDLING(text, errorCode, offset)\
1064 {\
1065 StringStream json(text); \
1066 BaseReaderHandler<> handler; \
1067 Reader reader; \
1068 reader.Parse<kParseIterativeFlag>(json, handler); \
1069 EXPECT_TRUE(reader.HasParseError()); \
1070 EXPECT_EQ(errorCode, reader.GetParseErrorCode()); \
1071 EXPECT_EQ(offset, reader.GetErrorOffset()); \
1072 }
1073
TEST(Reader,IterativeParsing_ErrorHandling)1074 TEST(Reader, IterativeParsing_ErrorHandling) {
1075 TESTERRORHANDLING("{\"a\": a}", kParseErrorValueInvalid, 6u);
1076
1077 TESTERRORHANDLING("", kParseErrorDocumentEmpty, 0u);
1078 TESTERRORHANDLING("{}{}", kParseErrorDocumentRootNotSingular, 2u);
1079
1080 TESTERRORHANDLING("{1}", kParseErrorObjectMissName, 1u);
1081 TESTERRORHANDLING("{\"a\", 1}", kParseErrorObjectMissColon, 4u);
1082 TESTERRORHANDLING("{\"a\"}", kParseErrorObjectMissColon, 4u);
1083 TESTERRORHANDLING("{\"a\": 1", kParseErrorObjectMissCommaOrCurlyBracket, 7u);
1084 TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket, 3u);
1085 TESTERRORHANDLING("{\"a: 1", kParseErrorStringMissQuotationMark, 5u);
1086
1087 // Any JSON value can be a valid root element in RFC7159.
1088 TESTERRORHANDLING("\"ab", kParseErrorStringMissQuotationMark, 2u);
1089 TESTERRORHANDLING("truE", kParseErrorValueInvalid, 3u);
1090 TESTERRORHANDLING("False", kParseErrorValueInvalid, 0u);
1091 TESTERRORHANDLING("true, false", kParseErrorDocumentRootNotSingular, 4u);
1092 TESTERRORHANDLING("false, false", kParseErrorDocumentRootNotSingular, 5u);
1093 TESTERRORHANDLING("nulL", kParseErrorValueInvalid, 3u);
1094 TESTERRORHANDLING("null , null", kParseErrorDocumentRootNotSingular, 5u);
1095 TESTERRORHANDLING("1a", kParseErrorDocumentRootNotSingular, 1u);
1096 }
1097
1098 template<typename Encoding = UTF8<> >
1099 struct IterativeParsingReaderHandler {
1100 typedef typename Encoding::Ch Ch;
1101
1102 const static int LOG_NULL = -1;
1103 const static int LOG_BOOL = -2;
1104 const static int LOG_INT = -3;
1105 const static int LOG_UINT = -4;
1106 const static int LOG_INT64 = -5;
1107 const static int LOG_UINT64 = -6;
1108 const static int LOG_DOUBLE = -7;
1109 const static int LOG_STRING = -8;
1110 const static int LOG_STARTOBJECT = -9;
1111 const static int LOG_KEY = -10;
1112 const static int LOG_ENDOBJECT = -11;
1113 const static int LOG_STARTARRAY = -12;
1114 const static int LOG_ENDARRAY = -13;
1115
1116 const static size_t LogCapacity = 256;
1117 int Logs[LogCapacity];
1118 size_t LogCount;
1119
IterativeParsingReaderHandlerIterativeParsingReaderHandler1120 IterativeParsingReaderHandler() : LogCount(0) {
1121 }
1122
NullIterativeParsingReaderHandler1123 bool Null() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_NULL; return true; }
1124
BoolIterativeParsingReaderHandler1125 bool Bool(bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_BOOL; return true; }
1126
IntIterativeParsingReaderHandler1127 bool Int(int) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1128
UintIterativeParsingReaderHandler1129 bool Uint(unsigned) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1130
Int64IterativeParsingReaderHandler1131 bool Int64(int64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT64; return true; }
1132
Uint64IterativeParsingReaderHandler1133 bool Uint64(uint64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_UINT64; return true; }
1134
DoubleIterativeParsingReaderHandler1135 bool Double(double) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_DOUBLE; return true; }
1136
StringIterativeParsingReaderHandler1137 bool String(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1138
StartObjectIterativeParsingReaderHandler1139 bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
1140
KeyIterativeParsingReaderHandler1141 bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
1142
EndObjectIterativeParsingReaderHandler1143 bool EndObject(SizeType c) {
1144 RAPIDJSON_ASSERT(LogCount < LogCapacity);
1145 Logs[LogCount++] = LOG_ENDOBJECT;
1146 Logs[LogCount++] = (int)c;
1147 return true;
1148 }
1149
StartArrayIterativeParsingReaderHandler1150 bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
1151
EndArrayIterativeParsingReaderHandler1152 bool EndArray(SizeType c) {
1153 RAPIDJSON_ASSERT(LogCount < LogCapacity);
1154 Logs[LogCount++] = LOG_ENDARRAY;
1155 Logs[LogCount++] = (int)c;
1156 return true;
1157 }
1158 };
1159
TEST(Reader,IterativeParsing_General)1160 TEST(Reader, IterativeParsing_General) {
1161 {
1162 StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1163 Reader reader;
1164 IterativeParsingReaderHandler<> handler;
1165
1166 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1167
1168 EXPECT_FALSE(r.IsError());
1169 EXPECT_FALSE(reader.HasParseError());
1170
1171 int e[] = {
1172 handler.LOG_STARTARRAY,
1173 handler.LOG_INT,
1174 handler.LOG_STARTOBJECT,
1175 handler.LOG_KEY,
1176 handler.LOG_STARTARRAY,
1177 handler.LOG_INT,
1178 handler.LOG_INT,
1179 handler.LOG_ENDARRAY, 2,
1180 handler.LOG_ENDOBJECT, 1,
1181 handler.LOG_NULL,
1182 handler.LOG_BOOL,
1183 handler.LOG_BOOL,
1184 handler.LOG_STRING,
1185 handler.LOG_DOUBLE,
1186 handler.LOG_ENDARRAY, 7
1187 };
1188
1189 EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1190
1191 for (size_t i = 0; i < handler.LogCount; ++i) {
1192 EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1193 }
1194 }
1195 }
1196
TEST(Reader,IterativeParsing_Count)1197 TEST(Reader, IterativeParsing_Count) {
1198 {
1199 StringStream is("[{}, {\"k\": 1}, [1], []]");
1200 Reader reader;
1201 IterativeParsingReaderHandler<> handler;
1202
1203 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1204
1205 EXPECT_FALSE(r.IsError());
1206 EXPECT_FALSE(reader.HasParseError());
1207
1208 int e[] = {
1209 handler.LOG_STARTARRAY,
1210 handler.LOG_STARTOBJECT,
1211 handler.LOG_ENDOBJECT, 0,
1212 handler.LOG_STARTOBJECT,
1213 handler.LOG_KEY,
1214 handler.LOG_INT,
1215 handler.LOG_ENDOBJECT, 1,
1216 handler.LOG_STARTARRAY,
1217 handler.LOG_INT,
1218 handler.LOG_ENDARRAY, 1,
1219 handler.LOG_STARTARRAY,
1220 handler.LOG_ENDARRAY, 0,
1221 handler.LOG_ENDARRAY, 4
1222 };
1223
1224 EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1225
1226 for (size_t i = 0; i < handler.LogCount; ++i) {
1227 EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1228 }
1229 }
1230 }
1231
1232 // Test iterative parsing on kParseErrorTermination.
1233 struct HandlerTerminateAtStartObject : public IterativeParsingReaderHandler<> {
StartObjectHandlerTerminateAtStartObject1234 bool StartObject() { return false; }
1235 };
1236
1237 struct HandlerTerminateAtStartArray : public IterativeParsingReaderHandler<> {
StartArrayHandlerTerminateAtStartArray1238 bool StartArray() { return false; }
1239 };
1240
1241 struct HandlerTerminateAtEndObject : public IterativeParsingReaderHandler<> {
EndObjectHandlerTerminateAtEndObject1242 bool EndObject(SizeType) { return false; }
1243 };
1244
1245 struct HandlerTerminateAtEndArray : public IterativeParsingReaderHandler<> {
EndArrayHandlerTerminateAtEndArray1246 bool EndArray(SizeType) { return false; }
1247 };
1248
TEST(Reader,IterativeParsing_ShortCircuit)1249 TEST(Reader, IterativeParsing_ShortCircuit) {
1250 {
1251 HandlerTerminateAtStartObject handler;
1252 Reader reader;
1253 StringStream is("[1, {}]");
1254
1255 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1256
1257 EXPECT_TRUE(reader.HasParseError());
1258 EXPECT_EQ(kParseErrorTermination, r.Code());
1259 EXPECT_EQ(4u, r.Offset());
1260 }
1261
1262 {
1263 HandlerTerminateAtStartArray handler;
1264 Reader reader;
1265 StringStream is("{\"a\": []}");
1266
1267 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1268
1269 EXPECT_TRUE(reader.HasParseError());
1270 EXPECT_EQ(kParseErrorTermination, r.Code());
1271 EXPECT_EQ(6u, r.Offset());
1272 }
1273
1274 {
1275 HandlerTerminateAtEndObject handler;
1276 Reader reader;
1277 StringStream is("[1, {}]");
1278
1279 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1280
1281 EXPECT_TRUE(reader.HasParseError());
1282 EXPECT_EQ(kParseErrorTermination, r.Code());
1283 EXPECT_EQ(5u, r.Offset());
1284 }
1285
1286 {
1287 HandlerTerminateAtEndArray handler;
1288 Reader reader;
1289 StringStream is("{\"a\": []}");
1290
1291 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1292
1293 EXPECT_TRUE(reader.HasParseError());
1294 EXPECT_EQ(kParseErrorTermination, r.Code());
1295 EXPECT_EQ(7u, r.Offset());
1296 }
1297 }
1298
1299 // For covering BaseReaderHandler default functions
TEST(Reader,BaseReaderHandler_Default)1300 TEST(Reader, BaseReaderHandler_Default) {
1301 BaseReaderHandler<> h;
1302 Reader reader;
1303 StringStream is("[null, true, -1, 1, -1234567890123456789, 1234567890123456789, 3.14, \"s\", { \"a\" : 1 }]");
1304 EXPECT_TRUE(reader.Parse(is, h));
1305 }
1306
1307 template <int e>
1308 struct TerminateHandler {
NullTerminateHandler1309 bool Null() { return e != 0; }
BoolTerminateHandler1310 bool Bool(bool) { return e != 1; }
IntTerminateHandler1311 bool Int(int) { return e != 2; }
UintTerminateHandler1312 bool Uint(unsigned) { return e != 3; }
Int64TerminateHandler1313 bool Int64(int64_t) { return e != 4; }
Uint64TerminateHandler1314 bool Uint64(uint64_t) { return e != 5; }
DoubleTerminateHandler1315 bool Double(double) { return e != 6; }
StringTerminateHandler1316 bool String(const char*, SizeType, bool) { return e != 7; }
StartObjectTerminateHandler1317 bool StartObject() { return e != 8; }
KeyTerminateHandler1318 bool Key(const char*, SizeType, bool) { return e != 9; }
EndObjectTerminateHandler1319 bool EndObject(SizeType) { return e != 10; }
StartArrayTerminateHandler1320 bool StartArray() { return e != 11; }
EndArrayTerminateHandler1321 bool EndArray(SizeType) { return e != 12; }
1322 };
1323
1324 #define TEST_TERMINATION(e, json)\
1325 {\
1326 Reader reader;\
1327 TerminateHandler<e> h;\
1328 StringStream is(json);\
1329 EXPECT_FALSE(reader.Parse(is, h));\
1330 EXPECT_EQ(kParseErrorTermination, reader.GetParseErrorCode());\
1331 }
1332
TEST(Reader,ParseTerminationByHandler)1333 TEST(Reader, ParseTerminationByHandler) {
1334 TEST_TERMINATION(0, "[null");
1335 TEST_TERMINATION(1, "[true");
1336 TEST_TERMINATION(1, "[false");
1337 TEST_TERMINATION(2, "[-1");
1338 TEST_TERMINATION(3, "[1");
1339 TEST_TERMINATION(4, "[-1234567890123456789");
1340 TEST_TERMINATION(5, "[1234567890123456789");
1341 TEST_TERMINATION(6, "[0.5]");
1342 TEST_TERMINATION(7, "[\"a\"");
1343 TEST_TERMINATION(8, "[{");
1344 TEST_TERMINATION(9, "[{\"a\"");
1345 TEST_TERMINATION(10, "[{}");
1346 TEST_TERMINATION(10, "[{\"a\":1}"); // non-empty object
1347 TEST_TERMINATION(11, "{\"a\":[");
1348 TEST_TERMINATION(12, "{\"a\":[]");
1349 TEST_TERMINATION(12, "{\"a\":[1]"); // non-empty array
1350 }
1351
1352 #ifdef __GNUC__
1353 RAPIDJSON_DIAG_POP
1354 #endif
1355