1 //
2 // Copyright 2015-2016 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "src/core/util/json/json.h"
18
19 #include <string.h>
20
21 #include <map>
22 #include <string>
23 #include <utility>
24
25 #include "absl/log/log.h"
26 #include "absl/status/status.h"
27 #include "absl/status/statusor.h"
28 #include "absl/strings/match.h"
29 #include "absl/strings/str_cat.h"
30 #include "gmock/gmock.h"
31 #include "gtest/gtest.h"
32 #include "src/core/util/json/json_reader.h"
33 #include "src/core/util/json/json_writer.h"
34 #include "test/core/test_util/test_config.h"
35
36 namespace grpc_core {
37
38 void ValidateValue(const Json& actual, const Json& expected);
39
ValidateObject(const Json::Object & actual,const Json::Object & expected)40 void ValidateObject(const Json::Object& actual, const Json::Object& expected) {
41 ASSERT_EQ(actual.size(), expected.size());
42 auto actual_it = actual.begin();
43 for (const auto& p : expected) {
44 EXPECT_EQ(actual_it->first, p.first);
45 ValidateValue(actual_it->second, p.second);
46 ++actual_it;
47 }
48 }
49
ValidateArray(const Json::Array & actual,const Json::Array & expected)50 void ValidateArray(const Json::Array& actual, const Json::Array& expected) {
51 ASSERT_EQ(actual.size(), expected.size());
52 for (size_t i = 0; i < expected.size(); ++i) {
53 ValidateValue(actual[i], expected[i]);
54 }
55 }
56
ValidateValue(const Json & actual,const Json & expected)57 void ValidateValue(const Json& actual, const Json& expected) {
58 ASSERT_EQ(actual.type(), expected.type());
59 switch (expected.type()) {
60 case Json::Type::kNull:
61 break;
62 case Json::Type::kBoolean:
63 EXPECT_EQ(actual.boolean(), expected.boolean());
64 break;
65 case Json::Type::kString:
66 case Json::Type::kNumber:
67 EXPECT_EQ(actual.string(), expected.string());
68 break;
69 case Json::Type::kObject:
70 ValidateObject(actual.object(), expected.object());
71 break;
72 case Json::Type::kArray:
73 ValidateArray(actual.array(), expected.array());
74 break;
75 }
76 }
77
RunSuccessTest(const char * input,const Json & expected,const char * expected_output)78 void RunSuccessTest(const char* input, const Json& expected,
79 const char* expected_output) {
80 LOG(INFO) << "parsing string \"" << input << "\" - should succeed";
81 auto json = JsonParse(input);
82 ASSERT_TRUE(json.ok()) << json.status();
83 ValidateValue(*json, expected);
84 std::string output = JsonDump(*json);
85 EXPECT_EQ(output, expected_output);
86 }
87
TEST(Json,Whitespace)88 TEST(Json, Whitespace) {
89 RunSuccessTest(" 0 ", Json::FromNumber(0), "0");
90 RunSuccessTest(" 1 ", Json::FromNumber(1), "1");
91 RunSuccessTest(" \" \" ", Json::FromString(" "), "\" \"");
92 RunSuccessTest(" \"a\" ", Json::FromString("a"), "\"a\"");
93 RunSuccessTest(" true ", Json::FromBool(true), "true");
94 }
95
TEST(Json,Utf16)96 TEST(Json, Utf16) {
97 RunSuccessTest("\"\\u0020\\\\\\u0010\\u000a\\u000D\"",
98 Json::FromString(" \\\u0010\n\r"), "\" \\\\\\u0010\\n\\r\"");
99 }
100
101 MATCHER(ContainsInvalidUtf8,
102 absl::StrCat(negation ? "Contains" : "Does not contain",
103 " invalid UTF-8 characters.")) {
104 auto json = JsonParse(arg);
105 return json.status().code() == absl::StatusCode::kInvalidArgument &&
106 absl::StrContains(json.status().message(), "JSON parsing failed");
107 }
108
TEST(Json,Utf8)109 TEST(Json, Utf8) {
110 RunSuccessTest("\"ßâñć௵⇒\"", Json::FromString("ßâñć௵⇒"),
111 "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"");
112 RunSuccessTest("\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"",
113 Json::FromString("ßâñć௵⇒"),
114 "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"");
115 // Testing UTF-8 character "", U+11D1E.
116 RunSuccessTest("\"\xf0\x9d\x84\x9e\"", Json::FromString("\xf0\x9d\x84\x9e"),
117 "\"\\ud834\\udd1e\"");
118 RunSuccessTest("\"\\ud834\\udd1e\"", Json::FromString("\xf0\x9d\x84\x9e"),
119 "\"\\ud834\\udd1e\"");
120 RunSuccessTest("{\"\\ud834\\udd1e\":0}",
121 Json::FromObject({{"\xf0\x9d\x84\x9e", Json::FromNumber(0)}}),
122 "{\"\\ud834\\udd1e\":0}");
123
124 /// For UTF-8 characters with length of 1 byte, the range of it is [0x00,
125 /// 0x7f].
126 EXPECT_THAT("\"\xa0\"", ContainsInvalidUtf8());
127
128 /// For UTF-8 characters with length of 2 bytes, the range of the first byte
129 /// is [0xc2, 0xdf], and the range of the second byte is [0x80, 0xbf].
130 EXPECT_THAT("\"\xc0\xbc\"", ContainsInvalidUtf8());
131 EXPECT_THAT("\"\xbc\xc0\"", ContainsInvalidUtf8());
132
133 /// Corner cases for UTF-8 characters with length of 3 bytes.
134 /// If the first byte is 0xe0, the range of second byte is [0xa0, 0xbf].
135 EXPECT_THAT("\"\xe0\x80\x80\"", ContainsInvalidUtf8());
136 /// If the first byte is 0xed, the range of second byte is [0x80, 0x9f].
137 EXPECT_THAT("\"\xed\xa0\x80\"", ContainsInvalidUtf8());
138
139 /// Corner cases for UTF-8 characters with length of 4 bytes.
140 /// If the first byte is 0xf0, the range of second byte is [0x90, 0xbf].
141 EXPECT_THAT("\"\xf0\x80\x80\x80\"", ContainsInvalidUtf8());
142 /// If the first byte is 0xf4, the range of second byte is [0x80, 0x8f].
143 EXPECT_THAT("\"\xf4\x90\x80\x80\"", ContainsInvalidUtf8());
144 /// The range of the first bytes is [0xf0, 0xf4].
145 EXPECT_THAT("\"\xf5\x80\x80\x80\"", ContainsInvalidUtf8());
146 }
147
TEST(Json,NestedEmptyContainers)148 TEST(Json, NestedEmptyContainers) {
149 RunSuccessTest(" [ [ ] , { } , [ ] ] ",
150 Json::FromArray({
151 Json::FromArray({}),
152 Json::FromObject({}),
153 Json::FromArray({}),
154 }),
155 "[[],{},[]]");
156 }
157
TEST(Json,EscapesAndControlCharactersInKeyStrings)158 TEST(Json, EscapesAndControlCharactersInKeyStrings) {
159 RunSuccessTest(" { \"\\u007f\x7f\\n\\r\\\"\\f\\b\\\\a , b\": 1, \"\": 0 } ",
160 Json::FromObject({
161 {"\u007f\u007f\n\r\"\f\b\\a , b", Json::FromNumber(1)},
162 {"", Json::FromNumber(0)},
163 }),
164 "{\"\":0,\"\\u007f\\u007f\\n\\r\\\"\\f\\b\\\\a , b\":1}");
165 }
166
TEST(Json,WriterCutsOffInvalidUtf8)167 TEST(Json, WriterCutsOffInvalidUtf8) {
168 EXPECT_EQ(JsonDump(Json::FromString("abc\xf0\x9d\x24")), "\"abc\"");
169 EXPECT_EQ(JsonDump(Json::FromString("\xff")), "\"\"");
170 }
171
TEST(Json,ValidNumbers)172 TEST(Json, ValidNumbers) {
173 RunSuccessTest("[0, 42 , 0.0123, 123.456]",
174 Json::FromArray({
175 Json::FromNumber(0),
176 Json::FromNumber(42),
177 Json::FromNumber("0.0123"),
178 Json::FromNumber("123.456"),
179 }),
180 "[0,42,0.0123,123.456]");
181 RunSuccessTest("[1e4,-53.235e-31, 0.3e+3]",
182 Json::FromArray({
183 Json::FromNumber("1e4"),
184 Json::FromNumber("-53.235e-31"),
185 Json::FromNumber("0.3e+3"),
186 }),
187 "[1e4,-53.235e-31,0.3e+3]");
188 }
189
TEST(Json,Keywords)190 TEST(Json, Keywords) {
191 RunSuccessTest("[true, false, null]",
192 Json::FromArray({
193 Json::FromBool(true),
194 Json::FromBool(false),
195 Json(),
196 }),
197 "[true,false,null]");
198 }
199
RunParseFailureTest(const char * input)200 void RunParseFailureTest(const char* input) {
201 LOG(INFO) << "parsing string \"" << input << "\" - should fail";
202 auto json = JsonParse(input);
203 EXPECT_FALSE(json.ok()) << "input: \"" << input << "\"";
204 }
205
TEST(Json,InvalidInput)206 TEST(Json, InvalidInput) {
207 RunParseFailureTest("\\");
208 RunParseFailureTest("nu ll");
209 RunParseFailureTest("{\"foo\": bar}");
210 RunParseFailureTest("{\"foo\": bar\"x\"}");
211 RunParseFailureTest("fals");
212 RunParseFailureTest("0,0 ");
213 RunParseFailureTest("\"foo\",[]");
214 RunParseFailureTest("{\"field\": {},}");
215 RunParseFailureTest("[{},]");
216 RunParseFailureTest("{\"field\": [],}");
217 RunParseFailureTest("[[],]");
218 }
219
TEST(Json,UnterminatedString)220 TEST(Json, UnterminatedString) { RunParseFailureTest("\"\\x"); }
221
TEST(Json,InvalidUtf16)222 TEST(Json, InvalidUtf16) {
223 RunParseFailureTest("\"\\u123x");
224 RunParseFailureTest("{\"\\u123x");
225 }
226
TEST(Json,ImbalancedSurrogatePairs)227 TEST(Json, ImbalancedSurrogatePairs) {
228 RunParseFailureTest("\"\\ud834f");
229 RunParseFailureTest("{\"\\ud834f\":0}");
230 RunParseFailureTest("\"\\ud834\\n");
231 RunParseFailureTest("{\"\\ud834\\n\":0}");
232 RunParseFailureTest("\"\\udd1ef");
233 RunParseFailureTest("{\"\\udd1ef\":0}");
234 RunParseFailureTest("\"\\ud834\\ud834\"");
235 RunParseFailureTest("{\"\\ud834\\ud834\"\":0}");
236 RunParseFailureTest("\"\\ud834\\u1234\"");
237 RunParseFailureTest("{\"\\ud834\\u1234\"\":0}");
238 RunParseFailureTest("\"\\ud834]\"");
239 RunParseFailureTest("{\"\\ud834]\"\":0}");
240 RunParseFailureTest("\"\\ud834 \"");
241 RunParseFailureTest("{\"\\ud834 \"\":0}");
242 RunParseFailureTest("\"\\ud834\\\\\"");
243 RunParseFailureTest("{\"\\ud834\\\\\"\":0}");
244 }
245
TEST(Json,EmbeddedInvalidWhitechars)246 TEST(Json, EmbeddedInvalidWhitechars) {
247 RunParseFailureTest("\"\n\"");
248 RunParseFailureTest("\"\t\"");
249 }
250
TEST(Json,EmptyString)251 TEST(Json, EmptyString) { RunParseFailureTest(""); }
252
TEST(Json,ExtraCharsAtEndOfParsing)253 TEST(Json, ExtraCharsAtEndOfParsing) {
254 RunParseFailureTest("{},");
255 RunParseFailureTest("{}x");
256 }
257
TEST(Json,ImbalancedContainers)258 TEST(Json, ImbalancedContainers) {
259 RunParseFailureTest("{}}");
260 RunParseFailureTest("[]]");
261 RunParseFailureTest("{{}");
262 RunParseFailureTest("[[]");
263 RunParseFailureTest("[}");
264 RunParseFailureTest("{]");
265 }
266
TEST(Json,BadContainers)267 TEST(Json, BadContainers) {
268 RunParseFailureTest("{x}");
269 RunParseFailureTest("{x=0,y}");
270 }
271
TEST(Json,DuplicateObjectKeys)272 TEST(Json, DuplicateObjectKeys) { RunParseFailureTest("{\"x\": 1, \"x\": 1}"); }
273
TEST(Json,TrailingComma)274 TEST(Json, TrailingComma) {
275 RunParseFailureTest("{,}");
276 RunParseFailureTest("[1,2,3,4,]");
277 RunParseFailureTest("{\"a\": 1, }");
278 }
279
TEST(Json,KeySyntaxInArray)280 TEST(Json, KeySyntaxInArray) { RunParseFailureTest("[\"x\":0]"); }
281
TEST(Json,InvalidNumbers)282 TEST(Json, InvalidNumbers) {
283 RunParseFailureTest("1.");
284 RunParseFailureTest("1e");
285 RunParseFailureTest(".12");
286 RunParseFailureTest("1.x");
287 RunParseFailureTest("1.12x");
288 RunParseFailureTest("1ex");
289 RunParseFailureTest("1e12x");
290 RunParseFailureTest(".12x");
291 RunParseFailureTest("000");
292 };
293
TEST(Json,Equality)294 TEST(Json, Equality) {
295 // Null.
296 EXPECT_EQ(Json(), Json());
297 // Numbers.
298 EXPECT_EQ(Json::FromNumber(1), Json::FromNumber(1));
299 EXPECT_NE(Json::FromNumber(1), Json::FromNumber(2));
300 EXPECT_EQ(Json::FromNumber(1), Json::FromNumber("1"));
301 EXPECT_EQ(Json::FromNumber("-5e5"), Json::FromNumber("-5e5"));
302 // Booleans.
303 EXPECT_EQ(Json::FromBool(true), Json::FromBool(true));
304 EXPECT_EQ(Json::FromBool(false), Json::FromBool(false));
305 EXPECT_NE(Json::FromBool(true), Json::FromBool(false));
306 // Strings.
307 EXPECT_EQ(Json::FromString("foo"), Json::FromString("foo"));
308 EXPECT_NE(Json::FromString("foo"), Json::FromString("bar"));
309 // Arrays.
310 EXPECT_EQ(Json::FromArray({Json::FromString("foo")}),
311 Json::FromArray({Json::FromString("foo")}));
312 EXPECT_NE(Json::FromArray({Json::FromString("foo")}),
313 Json::FromArray({Json::FromString("bar")}));
314 // Objects.
315 EXPECT_EQ(Json::FromObject({{"foo", Json::FromNumber(1)}}),
316 Json::FromObject({{"foo", Json::FromNumber(1)}}));
317 EXPECT_NE(Json::FromObject({{"foo", Json::FromNumber(1)}}),
318 Json::FromObject({{"foo", Json::FromNumber(2)}}));
319 EXPECT_NE(Json::FromObject({{"foo", Json::FromNumber(1)}}),
320 Json::FromObject({{"bar", Json::FromNumber(1)}}));
321 // Differing types.
322 EXPECT_NE(Json::FromNumber(1), Json::FromString("foo"));
323 EXPECT_NE(Json::FromNumber(1), Json::FromBool(true));
324 EXPECT_NE(Json::FromNumber(1), Json::FromArray({}));
325 EXPECT_NE(Json::FromNumber(1), Json::FromObject({}));
326 EXPECT_NE(Json::FromNumber(1), Json());
327 }
328
329 } // namespace grpc_core
330
main(int argc,char ** argv)331 int main(int argc, char** argv) {
332 grpc::testing::TestEnvironment env(&argc, argv);
333 ::testing::InitGoogleTest(&argc, argv);
334 return RUN_ALL_TESTS();
335 }
336