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/document.h"
18
19 using namespace rapidjson;
20
ReadFile(const char * filename,size_t & length)21 static char* ReadFile(const char* filename, size_t& length) {
22 const char *paths[] = {
23 "jsonchecker",
24 "bin/jsonchecker",
25 "../bin/jsonchecker",
26 "../../bin/jsonchecker",
27 "../../../bin/jsonchecker"
28 };
29 char buffer[1024];
30 FILE *fp = 0;
31 for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
32 sprintf(buffer, "%s/%s", paths[i], filename);
33 fp = fopen(buffer, "rb");
34 if (fp)
35 break;
36 }
37
38 if (!fp)
39 return 0;
40
41 fseek(fp, 0, SEEK_END);
42 length = static_cast<size_t>(ftell(fp));
43 fseek(fp, 0, SEEK_SET);
44 char* json = static_cast<char*>(malloc(length + 1));
45 size_t readLength = fread(json, 1, length, fp);
46 json[readLength] = '\0';
47 fclose(fp);
48 return json;
49 }
50
51 struct NoOpHandler {
NullNoOpHandler52 bool Null() { return true; }
BoolNoOpHandler53 bool Bool(bool) { return true; }
IntNoOpHandler54 bool Int(int) { return true; }
UintNoOpHandler55 bool Uint(unsigned) { return true; }
Int64NoOpHandler56 bool Int64(int64_t) { return true; }
Uint64NoOpHandler57 bool Uint64(uint64_t) { return true; }
DoubleNoOpHandler58 bool Double(double) { return true; }
RawNumberNoOpHandler59 bool RawNumber(const char*, SizeType, bool) { return true; }
StringNoOpHandler60 bool String(const char*, SizeType, bool) { return true; }
StartObjectNoOpHandler61 bool StartObject() { return true; }
KeyNoOpHandler62 bool Key(const char*, SizeType, bool) { return true; }
EndObjectNoOpHandler63 bool EndObject(SizeType) { return true; }
StartArrayNoOpHandler64 bool StartArray() { return true; }
EndArrayNoOpHandler65 bool EndArray(SizeType) { return true; }
66 };
67
68
TEST(JsonChecker,Reader)69 TEST(JsonChecker, Reader) {
70 char filename[256];
71
72 // jsonchecker/failXX.json
73 for (int i = 1; i <= 33; i++) {
74 if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159).
75 continue;
76 if (i == 18) // fail18.json is valid in rapidjson, which has no limitation on depth of nesting.
77 continue;
78
79 sprintf(filename, "fail%d.json", i);
80 size_t length;
81 char* json = ReadFile(filename, length);
82 if (!json) {
83 printf("jsonchecker file %s not found", filename);
84 ADD_FAILURE();
85 continue;
86 }
87
88 // Test stack-based parsing.
89 GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
90 document.Parse(json);
91 EXPECT_TRUE(document.HasParseError()) << filename;
92
93 // Test iterative parsing.
94 document.Parse<kParseIterativeFlag>(json);
95 EXPECT_TRUE(document.HasParseError()) << filename;
96
97 // Test iterative pull-parsing.
98 Reader reader;
99 StringStream ss(json);
100 NoOpHandler h;
101 reader.IterativeParseInit();
102 while (!reader.IterativeParseComplete()) {
103 if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h))
104 break;
105 }
106 EXPECT_TRUE(reader.HasParseError()) << filename;
107
108 free(json);
109 }
110
111 // passX.json
112 for (int i = 1; i <= 3; i++) {
113 sprintf(filename, "pass%d.json", i);
114 size_t length;
115 char* json = ReadFile(filename, length);
116 if (!json) {
117 printf("jsonchecker file %s not found", filename);
118 continue;
119 }
120
121 // Test stack-based parsing.
122 GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
123 document.Parse(json);
124 EXPECT_FALSE(document.HasParseError()) << filename;
125
126 // Test iterative parsing.
127 document.Parse<kParseIterativeFlag>(json);
128 EXPECT_FALSE(document.HasParseError()) << filename;
129
130 // Test iterative pull-parsing.
131 Reader reader;
132 StringStream ss(json);
133 NoOpHandler h;
134 reader.IterativeParseInit();
135 while (!reader.IterativeParseComplete()) {
136 if (!reader.IterativeParseNext<kParseDefaultFlags>(ss, h))
137 break;
138 }
139 EXPECT_FALSE(reader.HasParseError()) << filename;
140
141 free(json);
142 }
143 }
144