]> git.proxmox.com Git - ceph.git/blame - ceph/src/rapidjson/test/unittest/readertest.cpp
buildsys: change download over to reef release
[ceph.git] / ceph / src / rapidjson / test / unittest / readertest.cpp
CommitLineData
31f18b77
FG
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#include <limits>
23
24using namespace rapidjson;
25
26RAPIDJSON_DIAG_PUSH
27#ifdef __GNUC__
28RAPIDJSON_DIAG_OFF(effc++)
29RAPIDJSON_DIAG_OFF(float-equal)
30RAPIDJSON_DIAG_OFF(missing-noreturn)
31#if __GNUC__ >= 7
32RAPIDJSON_DIAG_OFF(dangling-else)
33#endif
34#endif // __GNUC__
35
36#ifdef __clang__
37RAPIDJSON_DIAG_OFF(variadic-macros)
38RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
39#endif
40
41template<bool expect>
42struct ParseBoolHandler : BaseReaderHandler<UTF8<>, ParseBoolHandler<expect> > {
43 ParseBoolHandler() : step_(0) {}
44 bool Default() { ADD_FAILURE(); return false; }
45 // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version.
46 // Workaround with EXPECT_TRUE().
47 bool Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; return true; }
48
49 unsigned step_;
50};
51
52TEST(Reader, ParseTrue) {
53 StringStream s("true");
54 ParseBoolHandler<true> h;
55 Reader reader;
56 reader.Parse(s, h);
57 EXPECT_EQ(1u, h.step_);
58}
59
60TEST(Reader, ParseFalse) {
61 StringStream s("false");
62 ParseBoolHandler<false> h;
63 Reader reader;
64 reader.Parse(s, h);
65 EXPECT_EQ(1u, h.step_);
66}
67
68struct ParseIntHandler : BaseReaderHandler<UTF8<>, ParseIntHandler> {
69 ParseIntHandler() : step_(0), actual_() {}
70 bool Default() { ADD_FAILURE(); return false; }
71 bool Int(int i) { actual_ = i; step_++; return true; }
72
73 unsigned step_;
74 int actual_;
75};
76
77struct ParseUintHandler : BaseReaderHandler<UTF8<>, ParseUintHandler> {
78 ParseUintHandler() : step_(0), actual_() {}
79 bool Default() { ADD_FAILURE(); return false; }
80 bool Uint(unsigned i) { actual_ = i; step_++; return true; }
81
82 unsigned step_;
83 unsigned actual_;
84};
85
86struct ParseInt64Handler : BaseReaderHandler<UTF8<>, ParseInt64Handler> {
87 ParseInt64Handler() : step_(0), actual_() {}
88 bool Default() { ADD_FAILURE(); return false; }
89 bool Int64(int64_t i) { actual_ = i; step_++; return true; }
90
91 unsigned step_;
92 int64_t actual_;
93};
94
95struct ParseUint64Handler : BaseReaderHandler<UTF8<>, ParseUint64Handler> {
96 ParseUint64Handler() : step_(0), actual_() {}
97 bool Default() { ADD_FAILURE(); return false; }
98 bool Uint64(uint64_t i) { actual_ = i; step_++; return true; }
99
100 unsigned step_;
101 uint64_t actual_;
102};
103
104struct ParseDoubleHandler : BaseReaderHandler<UTF8<>, ParseDoubleHandler> {
105 ParseDoubleHandler() : step_(0), actual_() {}
106 bool Default() { ADD_FAILURE(); return false; }
107 bool Double(double d) { actual_ = d; step_++; return true; }
108
109 unsigned step_;
110 double actual_;
111};
112
113TEST(Reader, ParseNumber_Integer) {
114#define TEST_INTEGER(Handler, str, x) \
115 { \
116 StringStream s(str); \
117 Handler h; \
118 Reader reader; \
119 reader.Parse(s, h); \
120 EXPECT_EQ(1u, h.step_); \
121 EXPECT_EQ(x, h.actual_); \
122 }
123
124 TEST_INTEGER(ParseUintHandler, "0", 0u);
125 TEST_INTEGER(ParseUintHandler, "123", 123u);
126 TEST_INTEGER(ParseUintHandler, "2147483648", 2147483648u); // 2^31 - 1 (cannot be stored in int)
127 TEST_INTEGER(ParseUintHandler, "4294967295", 4294967295u);
128
129 TEST_INTEGER(ParseIntHandler, "-123", -123);
130 TEST_INTEGER(ParseIntHandler, "-2147483648", static_cast<int32_t>(0x80000000)); // -2^31 (min of int)
131
132 TEST_INTEGER(ParseUint64Handler, "4294967296", RAPIDJSON_UINT64_C2(1, 0)); // 2^32 (max of unsigned + 1, force to use uint64_t)
133 TEST_INTEGER(ParseUint64Handler, "18446744073709551615", RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)); // 2^64 - 1 (max of uint64_t)
134
135 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)
136 TEST_INTEGER(ParseInt64Handler, "-9223372036854775808", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))); // -2^63 (min of int64_t)
137
138 // Random test for uint32_t/int32_t
139 {
140 union {
141 uint32_t u;
142 int32_t i;
143 }u;
144 Random r;
145
146 for (unsigned i = 0; i < 100000; i++) {
147 u.u = r();
148
149 char buffer[32];
150 *internal::u32toa(u.u, buffer) = '\0';
151 TEST_INTEGER(ParseUintHandler, buffer, u.u);
152
153 if (u.i < 0) {
154 *internal::i32toa(u.i, buffer) = '\0';
155 TEST_INTEGER(ParseIntHandler, buffer, u.i);
156 }
157 }
158 }
159
160 // Random test for uint64_t/int64_t
161 {
162 union {
163 uint64_t u;
164 int64_t i;
165 }u;
166 Random r;
167
168 for (unsigned i = 0; i < 100000; i++) {
169 u.u = uint64_t(r()) << 32;
170 u.u |= r();
171
172 char buffer[32];
173 if (u.u > uint64_t(4294967295u)) {
174 *internal::u64toa(u.u, buffer) = '\0';
175 TEST_INTEGER(ParseUint64Handler, buffer, u.u);
176 }
177
178 if (u.i < -int64_t(2147483648u)) {
179 *internal::i64toa(u.i, buffer) = '\0';
180 TEST_INTEGER(ParseInt64Handler, buffer, u.i);
181 }
182 }
183 }
184#undef TEST_INTEGER
185}
186
187template<bool fullPrecision>
188static void TestParseDouble() {
189#define TEST_DOUBLE(fullPrecision, str, x) \
190 { \
191 StringStream s(str); \
192 ParseDoubleHandler h; \
193 Reader reader; \
194 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code()); \
195 EXPECT_EQ(1u, h.step_); \
196 internal::Double e(x), a(h.actual_); \
197 if (fullPrecision) { \
198 EXPECT_EQ(e.Uint64Value(), a.Uint64Value()); \
199 if (e.Uint64Value() != a.Uint64Value()) \
200 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \
201 } \
202 else { \
203 EXPECT_EQ(e.Sign(), a.Sign()); /* for 0.0 != -0.0 */ \
204 EXPECT_DOUBLE_EQ(x, h.actual_); \
205 } \
206 }
207
208 TEST_DOUBLE(fullPrecision, "0.0", 0.0);
209 TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289
210 TEST_DOUBLE(fullPrecision, "1.0", 1.0);
211 TEST_DOUBLE(fullPrecision, "-1.0", -1.0);
212 TEST_DOUBLE(fullPrecision, "1.5", 1.5);
213 TEST_DOUBLE(fullPrecision, "-1.5", -1.5);
214 TEST_DOUBLE(fullPrecision, "3.1416", 3.1416);
215 TEST_DOUBLE(fullPrecision, "1E10", 1E10);
216 TEST_DOUBLE(fullPrecision, "1e10", 1e10);
217 TEST_DOUBLE(fullPrecision, "1E+10", 1E+10);
218 TEST_DOUBLE(fullPrecision, "1E-10", 1E-10);
219 TEST_DOUBLE(fullPrecision, "-1E10", -1E10);
220 TEST_DOUBLE(fullPrecision, "-1e10", -1e10);
221 TEST_DOUBLE(fullPrecision, "-1E+10", -1E+10);
222 TEST_DOUBLE(fullPrecision, "-1E-10", -1E-10);
223 TEST_DOUBLE(fullPrecision, "1.234E+10", 1.234E+10);
224 TEST_DOUBLE(fullPrecision, "1.234E-10", 1.234E-10);
225 TEST_DOUBLE(fullPrecision, "1.79769e+308", 1.79769e+308);
226 TEST_DOUBLE(fullPrecision, "2.22507e-308", 2.22507e-308);
227 TEST_DOUBLE(fullPrecision, "-1.79769e+308", -1.79769e+308);
228 TEST_DOUBLE(fullPrecision, "-2.22507e-308", -2.22507e-308);
229 TEST_DOUBLE(fullPrecision, "4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal
230 TEST_DOUBLE(fullPrecision, "2.2250738585072009e-308", 2.2250738585072009e-308); // Max subnormal double
231 TEST_DOUBLE(fullPrecision, "2.2250738585072014e-308", 2.2250738585072014e-308); // Min normal positive double
232 TEST_DOUBLE(fullPrecision, "1.7976931348623157e+308", 1.7976931348623157e+308); // Max double
233 TEST_DOUBLE(fullPrecision, "1e-10000", 0.0); // must underflow
234 TEST_DOUBLE(fullPrecision, "18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double)
235 TEST_DOUBLE(fullPrecision, "-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double)
236 TEST_DOUBLE(fullPrecision, "0.9868011474609375", 0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120
237 TEST_DOUBLE(fullPrecision, "123e34", 123e34); // Fast Path Cases In Disguise
238 TEST_DOUBLE(fullPrecision, "45913141877270640000.0", 45913141877270640000.0);
239 TEST_DOUBLE(fullPrecision, "2.2250738585072011e-308", 2.2250738585072011e-308); // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
240 TEST_DOUBLE(fullPrecision, "1e-00011111111111", 0.0); // Issue #313
241 TEST_DOUBLE(fullPrecision, "-1e-00011111111111", -0.0);
242 TEST_DOUBLE(fullPrecision, "1e-214748363", 0.0); // Maximum supported negative exponent
243 TEST_DOUBLE(fullPrecision, "1e-214748364", 0.0);
244 TEST_DOUBLE(fullPrecision, "1e-21474836311", 0.0);
245 TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
246
247 // Since
248 // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... �� 10^-324
249 // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... �� 10 ^ -324
250 // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
251 TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
252
253 // More closer to normal/subnormal boundary
254 // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... �� 10^-308
255 TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
256 TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
257
258 // 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
259 // 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
260 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984375", 1.0); // round to even
261 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984374", 0.99999999999999989); // previous double
262 TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984376", 1.0); // next double
263 // 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125
264 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203125", 1.0); // round to even
265 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203124", 1.0); // previous double
266 TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203126", 1.00000000000000022); // next double
267
268 // Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc
269
270 TEST_DOUBLE(fullPrecision, "72057594037927928.0", 72057594037927928.0);
271 TEST_DOUBLE(fullPrecision, "72057594037927936.0", 72057594037927936.0);
272 TEST_DOUBLE(fullPrecision, "72057594037927932.0", 72057594037927936.0);
273 TEST_DOUBLE(fullPrecision, "7205759403792793199999e-5", 72057594037927928.0);
274 TEST_DOUBLE(fullPrecision, "7205759403792793200001e-5", 72057594037927936.0);
275
276 TEST_DOUBLE(fullPrecision, "9223372036854774784.0", 9223372036854774784.0);
277 TEST_DOUBLE(fullPrecision, "9223372036854775808.0", 9223372036854775808.0);
278 TEST_DOUBLE(fullPrecision, "9223372036854775296.0", 9223372036854775808.0);
279 TEST_DOUBLE(fullPrecision, "922337203685477529599999e-5", 9223372036854774784.0);
280 TEST_DOUBLE(fullPrecision, "922337203685477529600001e-5", 9223372036854775808.0);
281
282 TEST_DOUBLE(fullPrecision, "10141204801825834086073718800384", 10141204801825834086073718800384.0);
283 TEST_DOUBLE(fullPrecision, "10141204801825835211973625643008", 10141204801825835211973625643008.0);
284 TEST_DOUBLE(fullPrecision, "10141204801825834649023672221696", 10141204801825835211973625643008.0);
285 TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169599999e-5", 10141204801825834086073718800384.0);
286 TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169600001e-5", 10141204801825835211973625643008.0);
287
288 TEST_DOUBLE(fullPrecision, "5708990770823838890407843763683279797179383808", 5708990770823838890407843763683279797179383808.0);
289 TEST_DOUBLE(fullPrecision, "5708990770823839524233143877797980545530986496", 5708990770823839524233143877797980545530986496.0);
290 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152", 5708990770823839524233143877797980545530986496.0);
291 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185151999e-3", 5708990770823838890407843763683279797179383808.0);
292 TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152001e-3", 5708990770823839524233143877797980545530986496.0);
293
294 {
295 char n1e308[310]; // '1' followed by 308 '0'
296 n1e308[0] = '1';
297 for (int i = 1; i < 309; i++)
298 n1e308[i] = '0';
299 n1e308[309] = '\0';
300 TEST_DOUBLE(fullPrecision, n1e308, 1E308);
301 }
302
303 // Cover trimming
304 TEST_DOUBLE(fullPrecision,
305"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
306"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
307"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
308"6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
309"1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
310"5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
311"2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
312"7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
313"e-308",
314 2.2250738585072014e-308);
315
316 {
317 static const unsigned count = 100; // Tested with 1000000 locally
318 Random r;
319 Reader reader; // Reusing reader to prevent heap allocation
320
321 // Exhaustively test different exponents with random significant
322 for (uint64_t exp = 0; exp < 2047; exp++) {
323 ;
324 for (unsigned i = 0; i < count; i++) {
325 // Need to call r() in two statements for cross-platform coherent sequence.
326 uint64_t u = (exp << 52) | uint64_t(r() & 0x000FFFFF) << 32;
327 u |= uint64_t(r());
328 internal::Double d = internal::Double(u);
329
330 char buffer[32];
331 *internal::dtoa(d.Value(), buffer) = '\0';
332
333 StringStream s(buffer);
334 ParseDoubleHandler h;
335 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
336 EXPECT_EQ(1u, h.step_);
337 internal::Double a(h.actual_);
338 if (fullPrecision) {
339 EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
340 if (d.Uint64Value() != a.Uint64Value())
341 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
342 }
343 else {
344 EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
345 EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
346 }
347 }
348 }
349 }
350
351 // Issue #340
352 TEST_DOUBLE(fullPrecision, "7.450580596923828e-9", 7.450580596923828e-9);
353 {
354 internal::Double d(1.0);
355 for (int i = 0; i < 324; i++) {
356 char buffer[32];
357 *internal::dtoa(d.Value(), buffer) = '\0';
358
359 StringStream s(buffer);
360 ParseDoubleHandler h;
361 Reader reader;
362 ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
363 EXPECT_EQ(1u, h.step_);
364 internal::Double a(h.actual_);
365 if (fullPrecision) {
366 EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
367 if (d.Uint64Value() != a.Uint64Value())
368 printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
369 }
370 else {
371 EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
372 EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
373 }
374
375
376 d = d.Value() * 0.5;
377 }
378 }
379#undef TEST_DOUBLE
380}
381
382TEST(Reader, ParseNumber_NormalPrecisionDouble) {
383 TestParseDouble<false>();
384}
385
386TEST(Reader, ParseNumber_FullPrecisionDouble) {
387 TestParseDouble<true>();
388}
389
390TEST(Reader, ParseNumber_NormalPrecisionError) {
391 static unsigned count = 1000000;
392 Random r;
393
394 double ulpSum = 0.0;
395 double ulpMax = 0.0;
396 for (unsigned i = 0; i < count; i++) {
397 internal::Double e, a;
398 do {
399 // Need to call r() in two statements for cross-platform coherent sequence.
400 uint64_t u = uint64_t(r()) << 32;
401 u |= uint64_t(r());
402 e = u;
403 } while (e.IsNan() || e.IsInf() || !e.IsNormal());
404
405 char buffer[32];
406 *internal::dtoa(e.Value(), buffer) = '\0';
407
408 StringStream s(buffer);
409 ParseDoubleHandler h;
410 Reader reader;
411 ASSERT_EQ(kParseErrorNone, reader.Parse(s, h).Code());
412 EXPECT_EQ(1u, h.step_);
413
414 a = h.actual_;
415 uint64_t bias1 = e.ToBias();
416 uint64_t bias2 = a.ToBias();
417 double ulp = static_cast<double>(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1);
418 ulpMax = std::max(ulpMax, ulp);
419 ulpSum += ulp;
420 }
421 printf("ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax);
422}
423
424TEST(Reader, ParseNumber_Error) {
425#define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos) \
426 { \
427 char buffer[1001]; \
428 sprintf(buffer, "%s", str); \
429 InsituStringStream s(buffer); \
430 BaseReaderHandler<> h; \
431 Reader reader; \
432 EXPECT_FALSE(reader.Parse(s, h)); \
433 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
434 EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
435 EXPECT_EQ(streamPos, s.Tell());\
436 }
437
438 // Number too big to be stored in double.
439 {
440 char n1e309[311]; // '1' followed by 309 '0'
441 n1e309[0] = '1';
442 for (int i = 1; i < 310; i++)
443 n1e309[i] = '0';
444 n1e309[310] = '\0';
445 TEST_NUMBER_ERROR(kParseErrorNumberTooBig, n1e309, 0, 309);
446 }
447 TEST_NUMBER_ERROR(kParseErrorNumberTooBig, "1e309", 0, 5);
448
449 // Miss fraction part in number.
450 TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.", 2, 2);
451 TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.a", 2, 2);
452
453 // Miss exponent in number.
454 TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e", 2, 2);
455 TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e_", 2, 2);
456
457#undef TEST_NUMBER_ERROR
458}
459
460template <typename Encoding>
461struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encoding> > {
462 ParseStringHandler() : str_(0), length_(0), copy_() {}
463 ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
464
465 ParseStringHandler(const ParseStringHandler&);
466 ParseStringHandler& operator=(const ParseStringHandler&);
467
468 bool Default() { ADD_FAILURE(); return false; }
469 bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
470 EXPECT_EQ(0, str_);
471 if (copy) {
472 str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
473 memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
474 }
475 else
476 str_ = str;
477 length_ = length;
478 copy_ = copy;
479 return true;
480 }
481
482 const typename Encoding::Ch* str_;
483 size_t length_;
484 bool copy_;
485};
486
487TEST(Reader, ParseString) {
488#define TEST_STRING(Encoding, e, x) \
489 { \
490 Encoding::Ch* buffer = StrDup(x); \
491 GenericInsituStringStream<Encoding> is(buffer); \
492 ParseStringHandler<Encoding> h; \
493 GenericReader<Encoding, Encoding> reader; \
494 reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(is, h); \
495 EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h.str_)); \
496 EXPECT_EQ(StrLen(e), h.length_); \
497 free(buffer); \
498 GenericStringStream<Encoding> s(x); \
499 ParseStringHandler<Encoding> h2; \
500 GenericReader<Encoding, Encoding> reader2; \
501 reader2.Parse(s, h2); \
502 EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h2.str_)); \
503 EXPECT_EQ(StrLen(e), h2.length_); \
504 }
505
506 // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
507 // And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
508 // In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
509 // Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
510#define ARRAY(...) { __VA_ARGS__ }
511#define TEST_STRINGARRAY(Encoding, utype, array, x) \
512 { \
513 static const utype ue[] = array; \
514 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
515 TEST_STRING(Encoding, e, x); \
516 }
517
518#define TEST_STRINGARRAY2(Encoding, utype, earray, xarray) \
519 { \
520 static const utype ue[] = earray; \
521 static const utype xe[] = xarray; \
522 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
523 static const Encoding::Ch* x = reinterpret_cast<const Encoding::Ch *>(&xe[0]); \
524 TEST_STRING(Encoding, e, x); \
525 }
526
527 TEST_STRING(UTF8<>, "", "\"\"");
528 TEST_STRING(UTF8<>, "Hello", "\"Hello\"");
529 TEST_STRING(UTF8<>, "Hello\nWorld", "\"Hello\\nWorld\"");
530 TEST_STRING(UTF8<>, "\"\\/\b\f\n\r\t", "\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
531 TEST_STRING(UTF8<>, "\x24", "\"\\u0024\""); // Dollar sign U+0024
532 TEST_STRING(UTF8<>, "\xC2\xA2", "\"\\u00A2\""); // Cents sign U+00A2
533 TEST_STRING(UTF8<>, "\xE2\x82\xAC", "\"\\u20AC\""); // Euro sign U+20AC
534 TEST_STRING(UTF8<>, "\xF0\x9D\x84\x9E", "\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
535
536 // UTF16
537 TEST_STRING(UTF16<>, L"", L"\"\"");
538 TEST_STRING(UTF16<>, L"Hello", L"\"Hello\"");
539 TEST_STRING(UTF16<>, L"Hello\nWorld", L"\"Hello\\nWorld\"");
540 TEST_STRING(UTF16<>, L"\"\\/\b\f\n\r\t", L"\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
541 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x0024, 0x0000), L"\"\\u0024\"");
542 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x00A2, 0x0000), L"\"\\u00A2\""); // Cents sign U+00A2
543 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x20AC, 0x0000), L"\"\\u20AC\""); // Euro sign U+20AC
544 TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0xD834, 0xDD1E, 0x0000), L"\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
545
546 // UTF32
547 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\0'), ARRAY('\"', '\"', '\0'));
548 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\"', '\0'));
549 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'));
550 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\"', '\\', '/', '\b', '\f', '\n', '\r', '\t', '\0'), ARRAY('\"', '\\', '\"', '\\', '\\', '/', '\\', 'b', '\\', 'f', '\\', 'n', '\\', 'r', '\\', 't', '\"', '\0'));
551 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x00024, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', '2', '4', '\"', '\0'));
552 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x000A2, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', 'A', '2', '\"', '\0')); // Cents sign U+00A2
553 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x020AC, 0x0000), ARRAY('\"', '\\', 'u', '2', '0', 'A', 'C', '\"', '\0')); // Euro sign U+20AC
554 TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x1D11E, 0x0000), ARRAY('\"', '\\', 'u', 'D', '8', '3', '4', '\\', 'u', 'D', 'D', '1', 'E', '\"', '\0')); // G clef sign U+1D11E
555
556#undef TEST_STRINGARRAY
557#undef ARRAY
558#undef TEST_STRING
559
560 // Support of null character in string
561 {
562 StringStream s("\"Hello\\u0000World\"");
563 const char e[] = "Hello\0World";
564 ParseStringHandler<UTF8<> > h;
565 Reader reader;
566 reader.Parse(s, h);
567 EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1));
568 EXPECT_EQ(11u, h.length_);
569 }
570}
571
572TEST(Reader, ParseString_Transcoding) {
573 const char* x = "\"Hello\"";
574 const wchar_t* e = L"Hello";
575 GenericStringStream<UTF8<> > is(x);
576 GenericReader<UTF8<>, UTF16<> > reader;
577 ParseStringHandler<UTF16<> > h;
578 reader.Parse(is, h);
579 EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
580 EXPECT_EQ(StrLen(e), h.length_);
581}
582
583TEST(Reader, ParseString_TranscodingWithValidation) {
584 const char* x = "\"Hello\"";
585 const wchar_t* e = L"Hello";
586 GenericStringStream<UTF8<> > is(x);
587 GenericReader<UTF8<>, UTF16<> > reader;
588 ParseStringHandler<UTF16<> > h;
589 reader.Parse<kParseValidateEncodingFlag>(is, h);
590 EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
591 EXPECT_EQ(StrLen(e), h.length_);
592}
593
594TEST(Reader, ParseString_NonDestructive) {
595 StringStream s("\"Hello\\nWorld\"");
596 ParseStringHandler<UTF8<> > h;
597 Reader reader;
598 reader.Parse(s, h);
599 EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_));
600 EXPECT_EQ(11u, h.length_);
601}
602
603template <typename Encoding>
604ParseErrorCode TestString(const typename Encoding::Ch* str) {
605 GenericStringStream<Encoding> s(str);
606 BaseReaderHandler<Encoding> h;
607 GenericReader<Encoding, Encoding> reader;
608 reader.template Parse<kParseValidateEncodingFlag>(s, h);
609 return reader.GetParseErrorCode();
610}
611
612TEST(Reader, ParseString_Error) {
613#define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)\
614{\
615 GenericStringStream<UTF8<> > s(str);\
616 BaseReaderHandler<UTF8<> > h;\
617 GenericReader<UTF8<> , UTF8<> > reader;\
618 reader.Parse<kParseValidateEncodingFlag>(s, h);\
619 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
620 EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
621 EXPECT_EQ(streamPos, s.Tell());\
622}
623
624#define ARRAY(...) { __VA_ARGS__ }
625#define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array) \
626 { \
627 static const utype ue[] = array; \
628 static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
629 EXPECT_EQ(kParseErrorStringInvalidEncoding, TestString<Encoding>(e));\
630 /* decode error */\
631 GenericStringStream<Encoding> s(e);\
632 BaseReaderHandler<TargetEncoding> h;\
633 GenericReader<Encoding, TargetEncoding> reader;\
634 reader.Parse(s, h);\
635 EXPECT_EQ(kParseErrorStringInvalidEncoding, reader.GetParseErrorCode());\
636 }
637
638 // Invalid escape character in string.
639 TEST_STRING_ERROR(kParseErrorStringEscapeInvalid, "[\"\\a\"]", 2, 3);
640
641 // Incorrect hex digit after \\u escape in string.
642 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uABCG\"]", 2, 7);
643
644 // Quotation in \\u escape in string (Issue #288)
645 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uaaa\"]", 2, 7);
646 TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uD800\\uFFF\"]", 2, 13);
647
648 // The surrogate pair in string is invalid.
649 TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800X\"]", 2, 8);
650 TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800\\uFFFF\"]", 2, 14);
651
652 // Missing a closing quotation mark in string.
653 TEST_STRING_ERROR(kParseErrorStringMissQuotationMark, "[\"Test]", 7, 7);
654
655 // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
656
657 // 3 Malformed sequences
658
659 // 3.1 Unexpected continuation bytes
660 {
661 char e[] = { '[', '\"', 0, '\"', ']', '\0' };
662 for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
663 e[2] = static_cast<char>(c);
664 ParseErrorCode error = TestString<UTF8<> >(e);
665 EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
666 if (error != kParseErrorStringInvalidEncoding)
667 std::cout << static_cast<unsigned>(c) << std::endl;
668 }
669 }
670
671 // 3.2 Lonely start characters, 3.5 Impossible bytes
672 {
673 char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
674 for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
675 e[2] = static_cast<char>(c);
676 int streamPos;
677 if (c <= 0xC1u)
678 streamPos = 3; // 0xC0 - 0xC1
679 else if (c <= 0xDFu)
680 streamPos = 4; // 0xC2 - 0xDF
681 else if (c <= 0xEFu)
682 streamPos = 5; // 0xE0 - 0xEF
683 else if (c <= 0xF4u)
684 streamPos = 6; // 0xF0 - 0xF4
685 else
686 streamPos = 3; // 0xF5 - 0xFF
687 TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e, 2, streamPos);
688 }
689 }
690
691 // 4 Overlong sequences
692
693 // 4.1 Examples of an overlong ASCII character
694 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0'));
695 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0'));
696 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0'));
697
698 // 4.2 Maximum overlong sequences
699 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0'));
700 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0'));
701 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0'));
702
703 // 4.3 Overlong representation of the NUL character
704 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0'));
705 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0'));
706 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0'));
707
708 // 5 Illegal code positions
709
710 // 5.1 Single UTF-16 surrogates
711 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xA0u, 0x80u, '\"', ']', '\0'));
712 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xADu, 0xBFu, '\"', ']', '\0'));
713 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAEu, 0x80u, '\"', ']', '\0'));
714 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAFu, 0xBFu, '\"', ']', '\0'));
715 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xB0u, 0x80u, '\"', ']', '\0'));
716 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBEu, 0x80u, '\"', ']', '\0'));
717 TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBFu, 0xBFu, '\"', ']', '\0'));
718
719 // Malform UTF-16 sequences
720 TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xDC00, 0xDC00, '\"', ']', '\0'));
721 TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xD800, 0xD800, '\"', ']', '\0'));
722
723 // Malform UTF-32 sequence
724 TEST_STRINGENCODING_ERROR(UTF32<>, UTF8<>, unsigned, ARRAY('[', '\"', 0x110000, '\"', ']', '\0'));
725
726 // Malform ASCII sequence
727 TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x80u), '\"', ']', '\0'));
728
729#undef ARRAY
730#undef TEST_STRINGARRAY_ERROR
731}
732
733template <unsigned count>
734struct ParseArrayHandler : BaseReaderHandler<UTF8<>, ParseArrayHandler<count> > {
735 ParseArrayHandler() : step_(0) {}
736
737 bool Default() { ADD_FAILURE(); return false; }
738 bool Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; return true; }
739 bool StartArray() { EXPECT_EQ(0u, step_); step_++; return true; }
740 bool EndArray(SizeType) { step_++; return true; }
741
742 unsigned step_;
743};
744
745TEST(Reader, ParseEmptyArray) {
746 char *json = StrDup("[ ] ");
747 InsituStringStream s(json);
748 ParseArrayHandler<0> h;
749 Reader reader;
750 reader.Parse(s, h);
751 EXPECT_EQ(2u, h.step_);
752 free(json);
753}
754
755TEST(Reader, ParseArray) {
756 char *json = StrDup("[1, 2, 3, 4]");
757 InsituStringStream s(json);
758 ParseArrayHandler<4> h;
759 Reader reader;
760 reader.Parse(s, h);
761 EXPECT_EQ(6u, h.step_);
762 free(json);
763}
764
765TEST(Reader, ParseArray_Error) {
766#define TEST_ARRAY_ERROR(errorCode, str, errorOffset) \
767 { \
768 int streamPos = errorOffset; \
769 char buffer[1001]; \
770 strncpy(buffer, str, 1000); \
771 InsituStringStream s(buffer); \
772 BaseReaderHandler<> h; \
773 GenericReader<UTF8<>, UTF8<>, CrtAllocator> reader; \
774 EXPECT_FALSE(reader.Parse(s, h)); \
775 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
776 EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
777 EXPECT_EQ(streamPos, s.Tell());\
778 }
779
780 // Missing a comma or ']' after an array element.
781 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1", 2);
782 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1}", 2);
783 TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1 2]", 3);
784
785 // Array cannot have a trailing comma (without kParseTrailingCommasFlag);
786 // a value must follow a comma
787 TEST_ARRAY_ERROR(kParseErrorValueInvalid, "[1,]", 3);
788
789#undef TEST_ARRAY_ERROR
790}
791
792struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
793 ParseObjectHandler() : step_(0) {}
794
795 bool Default() { ADD_FAILURE(); return false; }
796 bool Null() { EXPECT_EQ(8u, step_); step_++; return true; }
797 bool Bool(bool b) {
798 switch(step_) {
799 case 4: EXPECT_TRUE(b); step_++; return true;
800 case 6: EXPECT_FALSE(b); step_++; return true;
801 default: ADD_FAILURE(); return false;
802 }
803 }
804 bool Int(int i) {
805 switch(step_) {
806 case 10: EXPECT_EQ(123, i); step_++; return true;
807 case 15: EXPECT_EQ(1, i); step_++; return true;
808 case 16: EXPECT_EQ(2, i); step_++; return true;
809 case 17: EXPECT_EQ(3, i); step_++; return true;
810 default: ADD_FAILURE(); return false;
811 }
812 }
813 bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
814 bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
815 bool String(const char* str, size_t, bool) {
816 switch(step_) {
817 case 1: EXPECT_STREQ("hello", str); step_++; return true;
818 case 2: EXPECT_STREQ("world", str); step_++; return true;
819 case 3: EXPECT_STREQ("t", str); step_++; return true;
820 case 5: EXPECT_STREQ("f", str); step_++; return true;
821 case 7: EXPECT_STREQ("n", str); step_++; return true;
822 case 9: EXPECT_STREQ("i", str); step_++; return true;
823 case 11: EXPECT_STREQ("pi", str); step_++; return true;
824 case 13: EXPECT_STREQ("a", str); step_++; return true;
825 default: ADD_FAILURE(); return false;
826 }
827 }
828 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
829 bool EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++; return true; }
830 bool StartArray() { EXPECT_EQ(14u, step_); step_++; return true; }
831 bool EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++; return true; }
832
833 unsigned step_;
834};
835
836TEST(Reader, ParseObject) {
837 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
838
839 // Insitu
840 {
841 char* json2 = StrDup(json);
842 InsituStringStream s(json2);
843 ParseObjectHandler h;
844 Reader reader;
845 reader.Parse<kParseInsituFlag>(s, h);
846 EXPECT_EQ(20u, h.step_);
847 free(json2);
848 }
849
850 // Normal
851 {
852 StringStream s(json);
853 ParseObjectHandler h;
854 Reader reader;
855 reader.Parse(s, h);
856 EXPECT_EQ(20u, h.step_);
857 }
858}
859
860struct ParseEmptyObjectHandler : BaseReaderHandler<UTF8<>, ParseEmptyObjectHandler> {
861 ParseEmptyObjectHandler() : step_(0) {}
862
863 bool Default() { ADD_FAILURE(); return false; }
864 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
865 bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
866
867 unsigned step_;
868};
869
870TEST(Reader, Parse_EmptyObject) {
871 StringStream s("{ } ");
872 ParseEmptyObjectHandler h;
873 Reader reader;
874 reader.Parse(s, h);
875 EXPECT_EQ(2u, h.step_);
876}
877
878struct ParseMultipleRootHandler : BaseReaderHandler<UTF8<>, ParseMultipleRootHandler> {
879 ParseMultipleRootHandler() : step_(0) {}
880
881 bool Default() { ADD_FAILURE(); return false; }
882 bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
883 bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
884 bool StartArray() { EXPECT_EQ(2u, step_); step_++; return true; }
885 bool EndArray(SizeType) { EXPECT_EQ(3u, step_); step_++; return true; }
886
887 unsigned step_;
888};
889
890template <unsigned parseFlags>
891void TestMultipleRoot() {
892 StringStream s("{}[] a");
893 ParseMultipleRootHandler h;
894 Reader reader;
895 EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
896 EXPECT_EQ(2u, h.step_);
897 EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
898 EXPECT_EQ(4u, h.step_);
899 EXPECT_EQ(' ', s.Take());
900 EXPECT_EQ('a', s.Take());
901}
902
903TEST(Reader, Parse_MultipleRoot) {
904 TestMultipleRoot<kParseStopWhenDoneFlag>();
905}
906
907TEST(Reader, ParseIterative_MultipleRoot) {
908 TestMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
909}
910
911template <unsigned parseFlags>
912void TestInsituMultipleRoot() {
913 char* buffer = strdup("{}[] a");
914 InsituStringStream s(buffer);
915 ParseMultipleRootHandler h;
916 Reader reader;
917 EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
918 EXPECT_EQ(2u, h.step_);
919 EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
920 EXPECT_EQ(4u, h.step_);
921 EXPECT_EQ(' ', s.Take());
922 EXPECT_EQ('a', s.Take());
923 free(buffer);
924}
925
926TEST(Reader, ParseInsitu_MultipleRoot) {
927 TestInsituMultipleRoot<kParseStopWhenDoneFlag>();
928}
929
930TEST(Reader, ParseInsituIterative_MultipleRoot) {
931 TestInsituMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
932}
933
934#define TEST_ERROR(errorCode, str, errorOffset) \
935 { \
936 int streamPos = errorOffset; \
937 char buffer[1001]; \
938 strncpy(buffer, str, 1000); \
939 InsituStringStream s(buffer); \
940 BaseReaderHandler<> h; \
941 Reader reader; \
942 EXPECT_FALSE(reader.Parse(s, h)); \
943 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
944 EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
945 EXPECT_EQ(streamPos, s.Tell());\
946 }
947
948TEST(Reader, ParseDocument_Error) {
949 // The document is empty.
950 TEST_ERROR(kParseErrorDocumentEmpty, "", 0);
951 TEST_ERROR(kParseErrorDocumentEmpty, " ", 1);
952 TEST_ERROR(kParseErrorDocumentEmpty, " \n", 2);
953
954 // The document root must not follow by other values.
955 TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0", 3);
956 TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0", 3);
957 TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []", 5);
958 TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}", 2);
959}
960
961TEST(Reader, ParseValue_Error) {
962 // Invalid value.
963 TEST_ERROR(kParseErrorValueInvalid, "nulL", 3);
964 TEST_ERROR(kParseErrorValueInvalid, "truE", 3);
965 TEST_ERROR(kParseErrorValueInvalid, "falsE", 4);
966 TEST_ERROR(kParseErrorValueInvalid, "a]", 0);
967 TEST_ERROR(kParseErrorValueInvalid, ".1", 0);
968}
969
970TEST(Reader, ParseObject_Error) {
971 // Missing a name for object member.
972 TEST_ERROR(kParseErrorObjectMissName, "{1}", 1);
973 TEST_ERROR(kParseErrorObjectMissName, "{:1}", 1);
974 TEST_ERROR(kParseErrorObjectMissName, "{null:1}", 1);
975 TEST_ERROR(kParseErrorObjectMissName, "{true:1}", 1);
976 TEST_ERROR(kParseErrorObjectMissName, "{false:1}", 1);
977 TEST_ERROR(kParseErrorObjectMissName, "{1:1}", 1);
978 TEST_ERROR(kParseErrorObjectMissName, "{[]:1}", 1);
979 TEST_ERROR(kParseErrorObjectMissName, "{{}:1}", 1);
980 TEST_ERROR(kParseErrorObjectMissName, "{xyz:1}", 1);
981
982 // Missing a colon after a name of object member.
983 TEST_ERROR(kParseErrorObjectMissColon, "{\"a\" 1}", 5);
984 TEST_ERROR(kParseErrorObjectMissColon, "{\"a\",1}", 4);
985
986 // Must be a comma or '}' after an object member
987 TEST_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, "{\"a\":1]", 6);
988
989 // Object cannot have a trailing comma (without kParseTrailingCommasFlag);
990 // an object member name must follow a comma
991 TEST_ERROR(kParseErrorObjectMissName, "{\"a\":1,}", 7);
992
993 // This tests that MemoryStream is checking the length in Peek().
994 {
995 MemoryStream ms("{\"a\"", 1);
996 BaseReaderHandler<> h;
997 Reader reader;
998 EXPECT_FALSE(reader.Parse<kParseStopWhenDoneFlag>(ms, h));
999 EXPECT_EQ(kParseErrorObjectMissName, reader.GetParseErrorCode());
1000 }
1001}
1002
1003#undef TEST_ERROR
1004
1005TEST(Reader, SkipWhitespace) {
1006 StringStream ss(" A \t\tB\n \n\nC\r\r \rD \t\n\r E");
1007 const char* expected = "ABCDE";
1008 for (size_t i = 0; i < 5; i++) {
1009 SkipWhitespace(ss);
1010 EXPECT_EQ(expected[i], ss.Take());
1011 }
1012}
1013
1014// Test implementing a stream without copy stream optimization.
1015// Clone from GenericStringStream except that copy constructor is disabled.
1016template <typename Encoding>
1017class CustomStringStream {
1018public:
1019 typedef typename Encoding::Ch Ch;
1020
1021 CustomStringStream(const Ch *src) : src_(src), head_(src) {}
1022
1023 Ch Peek() const { return *src_; }
1024 Ch Take() { return *src_++; }
1025 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1026
1027 Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
1028 void Put(Ch) { RAPIDJSON_ASSERT(false); }
1029 void Flush() { RAPIDJSON_ASSERT(false); }
1030 size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
1031
1032private:
1033 // Prohibit copy constructor & assignment operator.
1034 CustomStringStream(const CustomStringStream&);
1035 CustomStringStream& operator=(const CustomStringStream&);
1036
1037 const Ch* src_; //!< Current read position.
1038 const Ch* head_; //!< Original head of the string.
1039};
1040
1041// If the following code is compiled, it should generate compilation error as predicted.
1042// Because CustomStringStream<> is not copyable via making copy constructor private.
1043#if 0
1044namespace rapidjson {
1045
1046template <typename Encoding>
1047struct StreamTraits<CustomStringStream<Encoding> > {
1048 enum { copyOptimization = 1 };
1049};
1050
1051} // namespace rapidjson
1052#endif
1053
1054TEST(Reader, CustomStringStream) {
1055 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
1056 CustomStringStream<UTF8<char> > s(json);
1057 ParseObjectHandler h;
1058 Reader reader;
1059 reader.Parse(s, h);
1060 EXPECT_EQ(20u, h.step_);
1061}
1062
1063#include <sstream>
1064
1065class IStreamWrapper {
1066public:
1067 typedef char Ch;
1068
1069 IStreamWrapper(std::istream& is) : is_(is) {}
1070
1071 Ch Peek() const {
1072 int c = is_.peek();
1073 return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1074 }
1075
1076 Ch Take() {
1077 int c = is_.get();
1078 return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1079 }
1080
1081 size_t Tell() const { return static_cast<size_t>(is_.tellg()); }
1082
1083 Ch* PutBegin() { assert(false); return 0; }
1084 void Put(Ch) { assert(false); }
1085 void Flush() { assert(false); }
1086 size_t PutEnd(Ch*) { assert(false); return 0; }
1087
1088private:
1089 IStreamWrapper(const IStreamWrapper&);
1090 IStreamWrapper& operator=(const IStreamWrapper&);
1091
1092 std::istream& is_;
1093};
1094
1095TEST(Reader, Parse_IStreamWrapper_StringStream) {
1096 const char* json = "[1,2,3,4]";
1097
1098 std::stringstream ss(json);
1099 IStreamWrapper is(ss);
1100
1101 Reader reader;
1102 ParseArrayHandler<4> h;
1103 reader.Parse(is, h);
1104 EXPECT_FALSE(reader.HasParseError());
1105}
1106
1107// Test iterative parsing.
1108
1109#define TESTERRORHANDLING(text, errorCode, offset)\
1110{\
1111 int streamPos = offset; \
1112 StringStream json(text); \
1113 BaseReaderHandler<> handler; \
1114 Reader reader; \
1115 reader.Parse<kParseIterativeFlag>(json, handler); \
1116 EXPECT_TRUE(reader.HasParseError()); \
1117 EXPECT_EQ(errorCode, reader.GetParseErrorCode()); \
1118 EXPECT_EQ(offset, reader.GetErrorOffset()); \
1119 EXPECT_EQ(streamPos, json.Tell()); \
1120}
1121
1122TEST(Reader, IterativeParsing_ErrorHandling) {
1123 TESTERRORHANDLING("{\"a\": a}", kParseErrorValueInvalid, 6u);
1124
1125 TESTERRORHANDLING("", kParseErrorDocumentEmpty, 0u);
1126 TESTERRORHANDLING("{}{}", kParseErrorDocumentRootNotSingular, 2u);
1127
1128 TESTERRORHANDLING("{1}", kParseErrorObjectMissName, 1u);
1129 TESTERRORHANDLING("{\"a\", 1}", kParseErrorObjectMissColon, 4u);
1130 TESTERRORHANDLING("{\"a\"}", kParseErrorObjectMissColon, 4u);
1131 TESTERRORHANDLING("{\"a\": 1", kParseErrorObjectMissCommaOrCurlyBracket, 7u);
1132 TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket, 3u);
1133 TESTERRORHANDLING("{\"a: 1", kParseErrorStringMissQuotationMark, 6u);
1134 TESTERRORHANDLING("{\"a\":}", kParseErrorValueInvalid, 5u);
1135 TESTERRORHANDLING("{\"a\":]", kParseErrorValueInvalid, 5u);
1136 TESTERRORHANDLING("[1,2,}", kParseErrorValueInvalid, 5u);
1137 TESTERRORHANDLING("[}]", kParseErrorValueInvalid, 1u);
1138 TESTERRORHANDLING("[,]", kParseErrorValueInvalid, 1u);
1139 TESTERRORHANDLING("[1,,]", kParseErrorValueInvalid, 3u);
1140
1141 // Trailing commas are not allowed without kParseTrailingCommasFlag
1142 TESTERRORHANDLING("{\"a\": 1,}", kParseErrorObjectMissName, 8u);
1143 TESTERRORHANDLING("[1,2,3,]", kParseErrorValueInvalid, 7u);
1144
1145 // Any JSON value can be a valid root element in RFC7159.
1146 TESTERRORHANDLING("\"ab", kParseErrorStringMissQuotationMark, 3u);
1147 TESTERRORHANDLING("truE", kParseErrorValueInvalid, 3u);
1148 TESTERRORHANDLING("False", kParseErrorValueInvalid, 0u);
1149 TESTERRORHANDLING("true, false", kParseErrorDocumentRootNotSingular, 4u);
1150 TESTERRORHANDLING("false, false", kParseErrorDocumentRootNotSingular, 5u);
1151 TESTERRORHANDLING("nulL", kParseErrorValueInvalid, 3u);
1152 TESTERRORHANDLING("null , null", kParseErrorDocumentRootNotSingular, 5u);
1153 TESTERRORHANDLING("1a", kParseErrorDocumentRootNotSingular, 1u);
1154}
1155
1156template<typename Encoding = UTF8<> >
1157struct IterativeParsingReaderHandler {
1158 typedef typename Encoding::Ch Ch;
1159
1160 const static int LOG_NULL = -1;
1161 const static int LOG_BOOL = -2;
1162 const static int LOG_INT = -3;
1163 const static int LOG_UINT = -4;
1164 const static int LOG_INT64 = -5;
1165 const static int LOG_UINT64 = -6;
1166 const static int LOG_DOUBLE = -7;
1167 const static int LOG_STRING = -8;
1168 const static int LOG_STARTOBJECT = -9;
1169 const static int LOG_KEY = -10;
1170 const static int LOG_ENDOBJECT = -11;
1171 const static int LOG_STARTARRAY = -12;
1172 const static int LOG_ENDARRAY = -13;
1173
1174 const static size_t LogCapacity = 256;
1175 int Logs[LogCapacity];
1176 size_t LogCount;
1177
1178 IterativeParsingReaderHandler() : LogCount(0) {
1179 }
1180
1181 bool Null() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_NULL; return true; }
1182
1183 bool Bool(bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_BOOL; return true; }
1184
1185 bool Int(int) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1186
1187 bool Uint(unsigned) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1188
1189 bool Int64(int64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT64; return true; }
1190
1191 bool Uint64(uint64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_UINT64; return true; }
1192
1193 bool Double(double) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_DOUBLE; return true; }
1194
1195 bool RawNumber(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1196
1197 bool String(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1198
1199 bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
1200
1201 bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
1202
1203 bool EndObject(SizeType c) {
1204 RAPIDJSON_ASSERT(LogCount < LogCapacity);
1205 Logs[LogCount++] = LOG_ENDOBJECT;
1206 Logs[LogCount++] = static_cast<int>(c);
1207 return true;
1208 }
1209
1210 bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
1211
1212 bool EndArray(SizeType c) {
1213 RAPIDJSON_ASSERT(LogCount < LogCapacity);
1214 Logs[LogCount++] = LOG_ENDARRAY;
1215 Logs[LogCount++] = static_cast<int>(c);
1216 return true;
1217 }
1218};
1219
1220TEST(Reader, IterativeParsing_General) {
1221 {
1222 StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1223 Reader reader;
1224 IterativeParsingReaderHandler<> handler;
1225
1226 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1227
1228 EXPECT_FALSE(r.IsError());
1229 EXPECT_FALSE(reader.HasParseError());
1230
1231 int e[] = {
1232 handler.LOG_STARTARRAY,
1233 handler.LOG_INT,
1234 handler.LOG_STARTOBJECT,
1235 handler.LOG_KEY,
1236 handler.LOG_STARTARRAY,
1237 handler.LOG_INT,
1238 handler.LOG_INT,
1239 handler.LOG_ENDARRAY, 2,
1240 handler.LOG_ENDOBJECT, 1,
1241 handler.LOG_NULL,
1242 handler.LOG_BOOL,
1243 handler.LOG_BOOL,
1244 handler.LOG_STRING,
1245 handler.LOG_DOUBLE,
1246 handler.LOG_ENDARRAY, 7
1247 };
1248
1249 EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1250
1251 for (size_t i = 0; i < handler.LogCount; ++i) {
1252 EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1253 }
1254 }
1255}
1256
1257TEST(Reader, IterativeParsing_Count) {
1258 {
1259 StringStream is("[{}, {\"k\": 1}, [1], []]");
1260 Reader reader;
1261 IterativeParsingReaderHandler<> handler;
1262
1263 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1264
1265 EXPECT_FALSE(r.IsError());
1266 EXPECT_FALSE(reader.HasParseError());
1267
1268 int e[] = {
1269 handler.LOG_STARTARRAY,
1270 handler.LOG_STARTOBJECT,
1271 handler.LOG_ENDOBJECT, 0,
1272 handler.LOG_STARTOBJECT,
1273 handler.LOG_KEY,
1274 handler.LOG_INT,
1275 handler.LOG_ENDOBJECT, 1,
1276 handler.LOG_STARTARRAY,
1277 handler.LOG_INT,
1278 handler.LOG_ENDARRAY, 1,
1279 handler.LOG_STARTARRAY,
1280 handler.LOG_ENDARRAY, 0,
1281 handler.LOG_ENDARRAY, 4
1282 };
1283
1284 EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1285
1286 for (size_t i = 0; i < handler.LogCount; ++i) {
1287 EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1288 }
1289 }
1290}
1291
1292// Test iterative parsing on kParseErrorTermination.
1293struct HandlerTerminateAtStartObject : public IterativeParsingReaderHandler<> {
1294 bool StartObject() { return false; }
1295};
1296
1297struct HandlerTerminateAtStartArray : public IterativeParsingReaderHandler<> {
1298 bool StartArray() { return false; }
1299};
1300
1301struct HandlerTerminateAtEndObject : public IterativeParsingReaderHandler<> {
1302 bool EndObject(SizeType) { return false; }
1303};
1304
1305struct HandlerTerminateAtEndArray : public IterativeParsingReaderHandler<> {
1306 bool EndArray(SizeType) { return false; }
1307};
1308
1309TEST(Reader, IterativeParsing_ShortCircuit) {
1310 {
1311 HandlerTerminateAtStartObject handler;
1312 Reader reader;
1313 StringStream is("[1, {}]");
1314
1315 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1316
1317 EXPECT_TRUE(reader.HasParseError());
1318 EXPECT_EQ(kParseErrorTermination, r.Code());
1319 EXPECT_EQ(4u, r.Offset());
1320 }
1321
1322 {
1323 HandlerTerminateAtStartArray handler;
1324 Reader reader;
1325 StringStream is("{\"a\": []}");
1326
1327 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1328
1329 EXPECT_TRUE(reader.HasParseError());
1330 EXPECT_EQ(kParseErrorTermination, r.Code());
1331 EXPECT_EQ(6u, r.Offset());
1332 }
1333
1334 {
1335 HandlerTerminateAtEndObject handler;
1336 Reader reader;
1337 StringStream is("[1, {}]");
1338
1339 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1340
1341 EXPECT_TRUE(reader.HasParseError());
1342 EXPECT_EQ(kParseErrorTermination, r.Code());
1343 EXPECT_EQ(5u, r.Offset());
1344 }
1345
1346 {
1347 HandlerTerminateAtEndArray handler;
1348 Reader reader;
1349 StringStream is("{\"a\": []}");
1350
1351 ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1352
1353 EXPECT_TRUE(reader.HasParseError());
1354 EXPECT_EQ(kParseErrorTermination, r.Code());
1355 EXPECT_EQ(7u, r.Offset());
1356 }
1357}
1358
1359// For covering BaseReaderHandler default functions
1360TEST(Reader, BaseReaderHandler_Default) {
1361 BaseReaderHandler<> h;
1362 Reader reader;
1363 StringStream is("[null, true, -1, 1, -1234567890123456789, 1234567890123456789, 3.14, \"s\", { \"a\" : 1 }]");
1364 EXPECT_TRUE(reader.Parse(is, h));
1365}
1366
1367template <int e>
1368struct TerminateHandler {
1369 bool Null() { return e != 0; }
1370 bool Bool(bool) { return e != 1; }
1371 bool Int(int) { return e != 2; }
1372 bool Uint(unsigned) { return e != 3; }
1373 bool Int64(int64_t) { return e != 4; }
1374 bool Uint64(uint64_t) { return e != 5; }
1375 bool Double(double) { return e != 6; }
1376 bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1377 bool String(const char*, SizeType, bool) { return e != 8; }
1378 bool StartObject() { return e != 9; }
1379 bool Key(const char*, SizeType, bool) { return e != 10; }
1380 bool EndObject(SizeType) { return e != 11; }
1381 bool StartArray() { return e != 12; }
1382 bool EndArray(SizeType) { return e != 13; }
1383};
1384
1385#define TEST_TERMINATION(e, json)\
1386{\
1387 Reader reader;\
1388 TerminateHandler<e> h;\
1389 StringStream is(json);\
1390 EXPECT_FALSE(reader.Parse(is, h));\
1391 EXPECT_EQ(kParseErrorTermination, reader.GetParseErrorCode());\
1392}
1393
1394TEST(Reader, ParseTerminationByHandler) {
1395 TEST_TERMINATION(0, "[null");
1396 TEST_TERMINATION(1, "[true");
1397 TEST_TERMINATION(1, "[false");
1398 TEST_TERMINATION(2, "[-1");
1399 TEST_TERMINATION(3, "[1");
1400 TEST_TERMINATION(4, "[-1234567890123456789");
1401 TEST_TERMINATION(5, "[1234567890123456789");
1402 TEST_TERMINATION(6, "[0.5]");
1403 // RawNumber() is never called
1404 TEST_TERMINATION(8, "[\"a\"");
1405 TEST_TERMINATION(9, "[{");
1406 TEST_TERMINATION(10, "[{\"a\"");
1407 TEST_TERMINATION(11, "[{}");
1408 TEST_TERMINATION(11, "[{\"a\":1}"); // non-empty object
1409 TEST_TERMINATION(12, "{\"a\":[");
1410 TEST_TERMINATION(13, "{\"a\":[]");
1411 TEST_TERMINATION(13, "{\"a\":[1]"); // non-empty array
1412}
1413
1414TEST(Reader, ParseComments) {
1415 const char* json =
1416 "// Here is a one-line comment.\n"
1417 "{// And here's another one\n"
1418 " /*And here's an in-line one.*/\"hello\" : \"world\","
1419 " \"t\" :/* And one with '*' symbol*/true ,"
1420 "/* A multiline comment\n"
1421 " goes here*/"
1422 " \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3]"
1423 "}/*And the last one to be sure */";
1424
1425 StringStream s(json);
1426 ParseObjectHandler h;
1427 Reader reader;
1428 EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1429 EXPECT_EQ(20u, h.step_);
1430}
1431
1432TEST(Reader, ParseEmptyInlineComment) {
1433 const char* json = "{/**/\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1434
1435 StringStream s(json);
1436 ParseObjectHandler h;
1437 Reader reader;
1438 EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1439 EXPECT_EQ(20u, h.step_);
1440}
1441
1442TEST(Reader, ParseEmptyOnelineComment) {
1443 const char* json = "{//\n\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1444
1445 StringStream s(json);
1446 ParseObjectHandler h;
1447 Reader reader;
1448 EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1449 EXPECT_EQ(20u, h.step_);
1450}
1451
1452TEST(Reader, ParseMultipleCommentsInARow) {
1453 const char* json =
1454 "{/* first comment *//* second */\n"
1455 "/* third */ /*fourth*/// last one\n"
1456 "\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1457
1458 StringStream s(json);
1459 ParseObjectHandler h;
1460 Reader reader;
1461 EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1462 EXPECT_EQ(20u, h.step_);
1463}
1464
1465TEST(Reader, InlineCommentsAreDisabledByDefault) {
1466 {
1467 const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1468
1469 StringStream s(json);
1470 ParseObjectHandler h;
1471 Reader reader;
1472 EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1473 }
1474
1475 {
1476 const char* json =
1477 "{\"hello\" : /* Multiline comment starts here\n"
1478 " continues here\n"
1479 " and ends here */\"world\", \"t\" :true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1480
1481 StringStream s(json);
1482 ParseObjectHandler h;
1483 Reader reader;
1484 EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1485 }
1486}
1487
1488TEST(Reader, OnelineCommentsAreDisabledByDefault) {
1489 const char* json = "{// One-line comment\n\"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1490
1491 StringStream s(json);
1492 ParseObjectHandler h;
1493 Reader reader;
1494 EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1495}
1496
1497TEST(Reader, EofAfterOneLineComment) {
1498 const char* json = "{\"hello\" : \"world\" // EOF is here -->\0 \n}";
1499
1500 StringStream s(json);
1501 ParseObjectHandler h;
1502 Reader reader;
1503 EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1504 EXPECT_EQ(kParseErrorObjectMissCommaOrCurlyBracket, reader.GetParseErrorCode());
1505}
1506
1507TEST(Reader, IncompleteMultilineComment) {
1508 const char* json = "{\"hello\" : \"world\" /* EOF is here -->\0 */}";
1509
1510 StringStream s(json);
1511 ParseObjectHandler h;
1512 Reader reader;
1513 EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1514 EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1515}
1516
1517TEST(Reader, IncompleteMultilineComment2) {
1518 const char* json = "{\"hello\" : \"world\" /* *\0 */}";
1519
1520 StringStream s(json);
1521 ParseObjectHandler h;
1522 Reader reader;
1523 EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1524 EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1525}
1526
1527TEST(Reader, UnrecognizedComment) {
1528 const char* json = "{\"hello\" : \"world\" /! }";
1529
1530 StringStream s(json);
1531 ParseObjectHandler h;
1532 Reader reader;
1533 EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1534 EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1535}
1536
1537struct NumbersAsStringsHandler {
1538 bool Null() { return true; }
1539 bool Bool(bool) { return true; }
1540 bool Int(int) { return true; }
1541 bool Uint(unsigned) { return true; }
1542 bool Int64(int64_t) { return true; }
1543 bool Uint64(uint64_t) { return true; }
1544 bool Double(double) { return true; }
1545 // 'str' is not null-terminated
1546 bool RawNumber(const char* str, SizeType length, bool) {
1547 EXPECT_TRUE(str != 0);
1548 EXPECT_TRUE(expected_len_ == length);
1549 EXPECT_TRUE(strncmp(str, expected_, length) == 0);
1550 return true;
1551 }
1552 bool String(const char*, SizeType, bool) { return true; }
1553 bool StartObject() { return true; }
1554 bool Key(const char*, SizeType, bool) { return true; }
1555 bool EndObject(SizeType) { return true; }
1556 bool StartArray() { return true; }
1557 bool EndArray(SizeType) { return true; }
1558
1559 NumbersAsStringsHandler(const char* expected)
1560 : expected_(expected)
1561 , expected_len_(strlen(expected)) {}
1562
1563 const char* expected_;
1564 size_t expected_len_;
1565};
1566
1567TEST(Reader, NumbersAsStrings) {
1568 {
1569 const char* json = "{ \"pi\": 3.1416 } ";
1570 StringStream s(json);
1571 NumbersAsStringsHandler h("3.1416");
1572 Reader reader;
1573 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1574 }
1575 {
1576 char* json = StrDup("{ \"pi\": 3.1416 } ");
1577 InsituStringStream s(json);
1578 NumbersAsStringsHandler h("3.1416");
1579 Reader reader;
1580 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1581 free(json);
1582 }
1583 {
1584 const char* json = "{ \"gigabyte\": 1.0e9 } ";
1585 StringStream s(json);
1586 NumbersAsStringsHandler h("1.0e9");
1587 Reader reader;
1588 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1589 }
1590 {
1591 char* json = StrDup("{ \"gigabyte\": 1.0e9 } ");
1592 InsituStringStream s(json);
1593 NumbersAsStringsHandler h("1.0e9");
1594 Reader reader;
1595 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1596 free(json);
1597 }
1598 {
1599 const char* json = "{ \"pi\": 314.159e-2 } ";
1600 StringStream s(json);
1601 NumbersAsStringsHandler h("314.159e-2");
1602 Reader reader;
1603 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1604 }
1605 {
1606 char* json = StrDup("{ \"gigabyte\": 314.159e-2 } ");
1607 InsituStringStream s(json);
1608 NumbersAsStringsHandler h("314.159e-2");
1609 Reader reader;
1610 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1611 free(json);
1612 }
1613 {
1614 const char* json = "{ \"negative\": -1.54321 } ";
1615 StringStream s(json);
1616 NumbersAsStringsHandler h("-1.54321");
1617 Reader reader;
1618 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1619 }
1620 {
1621 char* json = StrDup("{ \"negative\": -1.54321 } ");
1622 InsituStringStream s(json);
1623 NumbersAsStringsHandler h("-1.54321");
1624 Reader reader;
1625 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1626 free(json);
1627 }
1628 {
1629 const char* json = "{ \"pi\": 314.159e-2 } ";
1630 std::stringstream ss(json);
1631 IStreamWrapper s(ss);
1632 NumbersAsStringsHandler h("314.159e-2");
1633 Reader reader;
1634 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1635 }
1636}
1637
1638template <unsigned extraFlags>
1639void TestTrailingCommas() {
1640 {
1641 StringStream s("[1,2,3,]");
1642 ParseArrayHandler<3> h;
1643 Reader reader;
1644 EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1645 EXPECT_EQ(5u, h.step_);
1646 }
1647 {
1648 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1649 "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}";
1650 StringStream s(json);
1651 ParseObjectHandler h;
1652 Reader reader;
1653 EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1654 EXPECT_EQ(20u, h.step_);
1655 }
1656 {
1657 // whitespace around trailing commas
1658 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1659 "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3\n,\n]\n,\n} ";
1660 StringStream s(json);
1661 ParseObjectHandler h;
1662 Reader reader;
1663 EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1664 EXPECT_EQ(20u, h.step_);
1665 }
1666 {
1667 // comments around trailing commas
1668 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null,"
1669 "\"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3/*test*/,/*test*/]/*test*/,/*test*/}";
1670 StringStream s(json);
1671 ParseObjectHandler h;
1672 Reader reader;
1673 EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag|kParseCommentsFlag>(s, h));
1674 EXPECT_EQ(20u, h.step_);
1675 }
1676}
1677
1678TEST(Reader, TrailingCommas) {
1679 TestTrailingCommas<kParseNoFlags>();
1680}
1681
1682TEST(Reader, TrailingCommasIterative) {
1683 TestTrailingCommas<kParseIterativeFlag>();
1684}
1685
1686template <unsigned extraFlags>
1687void TestMultipleTrailingCommaErrors() {
1688 // only a single trailing comma is allowed.
1689 {
1690 StringStream s("[1,2,3,,]");
1691 ParseArrayHandler<3> h;
1692 Reader reader;
1693 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1694 EXPECT_TRUE(reader.HasParseError());
1695 EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1696 EXPECT_EQ(7u, r.Offset());
1697 }
1698 {
1699 const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1700 "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}";
1701 StringStream s(json);
1702 ParseObjectHandler h;
1703 Reader reader;
1704 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1705 EXPECT_TRUE(reader.HasParseError());
1706 EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1707 EXPECT_EQ(95u, r.Offset());
1708 }
1709}
1710
1711TEST(Reader, MultipleTrailingCommaErrors) {
1712 TestMultipleTrailingCommaErrors<kParseNoFlags>();
1713}
1714
1715TEST(Reader, MultipleTrailingCommaErrorsIterative) {
1716 TestMultipleTrailingCommaErrors<kParseIterativeFlag>();
1717}
1718
1719template <unsigned extraFlags>
1720void TestEmptyExceptForCommaErrors() {
1721 // not allowed even with trailing commas enabled; the
1722 // trailing comma must follow a value.
1723 {
1724 StringStream s("[,]");
1725 ParseArrayHandler<3> h;
1726 Reader reader;
1727 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1728 EXPECT_TRUE(reader.HasParseError());
1729 EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1730 EXPECT_EQ(1u, r.Offset());
1731 }
1732 {
1733 StringStream s("{,}");
1734 ParseObjectHandler h;
1735 Reader reader;
1736 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1737 EXPECT_TRUE(reader.HasParseError());
1738 EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1739 EXPECT_EQ(1u, r.Offset());
1740 }
1741}
1742
1743TEST(Reader, EmptyExceptForCommaErrors) {
1744 TestEmptyExceptForCommaErrors<kParseNoFlags>();
1745}
1746
1747TEST(Reader, EmptyExceptForCommaErrorsIterative) {
1748 TestEmptyExceptForCommaErrors<kParseIterativeFlag>();
1749}
1750
1751template <unsigned extraFlags>
1752void TestTrailingCommaHandlerTermination() {
1753 {
1754 HandlerTerminateAtEndArray h;
1755 Reader reader;
1756 StringStream s("[1,2,3,]");
1757 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1758 EXPECT_TRUE(reader.HasParseError());
1759 EXPECT_EQ(kParseErrorTermination, r.Code());
1760 EXPECT_EQ(7u, r.Offset());
1761 }
1762 {
1763 HandlerTerminateAtEndObject h;
1764 Reader reader;
1765 StringStream s("{\"t\": true, \"f\": false,}");
1766 ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1767 EXPECT_TRUE(reader.HasParseError());
1768 EXPECT_EQ(kParseErrorTermination, r.Code());
1769 EXPECT_EQ(23u, r.Offset());
1770 }
1771}
1772
1773TEST(Reader, TrailingCommaHandlerTermination) {
1774 TestTrailingCommaHandlerTermination<kParseNoFlags>();
1775}
1776
1777TEST(Reader, TrailingCommaHandlerTerminationIterative) {
1778 TestTrailingCommaHandlerTermination<kParseIterativeFlag>();
1779}
1780
1781TEST(Reader, ParseNanAndInfinity) {
1782#define TEST_NAN_INF(str, x) \
1783 { \
1784 { \
1785 StringStream s(str); \
1786 ParseDoubleHandler h; \
1787 Reader reader; \
1788 ASSERT_EQ(kParseErrorNone, reader.Parse<kParseNanAndInfFlag>(s, h).Code()); \
1789 EXPECT_EQ(1u, h.step_); \
1790 internal::Double e(x), a(h.actual_); \
1791 EXPECT_EQ(e.IsNan(), a.IsNan()); \
1792 EXPECT_EQ(e.IsInf(), a.IsInf()); \
1793 if (!e.IsNan()) \
1794 EXPECT_EQ(e.Sign(), a.Sign()); \
1795 } \
1796 { \
1797 const char* json = "{ \"naninfdouble\": " str " } "; \
1798 StringStream s(json); \
1799 NumbersAsStringsHandler h(str); \
1800 Reader reader; \
1801 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1802 } \
1803 { \
1804 char* json = StrDup("{ \"naninfdouble\": " str " } "); \
1805 InsituStringStream s(json); \
1806 NumbersAsStringsHandler h(str); \
1807 Reader reader; \
1808 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1809 free(json); \
1810 } \
1811 }
1812#define TEST_NAN_INF_ERROR(errorCode, str, errorOffset) \
1813 { \
1814 int streamPos = errorOffset; \
1815 char buffer[1001]; \
1816 strncpy(buffer, str, 1000); \
1817 InsituStringStream s(buffer); \
1818 BaseReaderHandler<> h; \
1819 Reader reader; \
1820 EXPECT_FALSE(reader.Parse<kParseNanAndInfFlag>(s, h)); \
1821 EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
1822 EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
1823 EXPECT_EQ(streamPos, s.Tell());\
1824 }
1825
1826 double nan = std::numeric_limits<double>::quiet_NaN();
1827 double inf = std::numeric_limits<double>::infinity();
1828
1829 TEST_NAN_INF("NaN", nan);
1830 TEST_NAN_INF("-NaN", nan);
1831 TEST_NAN_INF("Inf", inf);
1832 TEST_NAN_INF("Infinity", inf);
1833 TEST_NAN_INF("-Inf", -inf);
1834 TEST_NAN_INF("-Infinity", -inf);
1835 TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "nan", 1);
1836 TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-nan", 1);
1837 TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NAN", 1);
1838 TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-Infinty", 6);
1839
1840#undef TEST_NAN_INF_ERROR
1841#undef TEST_NAN_INF
1842}
1843
1844RAPIDJSON_DIAG_POP