1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/json/json_parser.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10 #include <optional>
11
12 #include "base/json/json_reader.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/values.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace base {
18 namespace internal {
19
20 class JSONParserTest : public testing::Test {
21 public:
NewTestParser(const std::string & input,int options=JSON_PARSE_RFC)22 JSONParser* NewTestParser(const std::string& input,
23 int options = JSON_PARSE_RFC) {
24 JSONParser* parser = new JSONParser(options);
25 parser->input_ = input;
26 parser->index_ = 0;
27 return parser;
28 }
29
TestLastThree(JSONParser * parser)30 void TestLastThree(JSONParser* parser) {
31 EXPECT_EQ(',', *parser->PeekChar());
32 parser->ConsumeChar();
33 EXPECT_EQ('|', *parser->PeekChar());
34 parser->ConsumeChar();
35 EXPECT_EQ('\0', *parser->pos());
36 EXPECT_EQ(static_cast<size_t>(parser->index_), parser->input_.length());
37 }
38 };
39
TEST_F(JSONParserTest,NextChar)40 TEST_F(JSONParserTest, NextChar) {
41 std::string input("Hello world");
42 std::unique_ptr<JSONParser> parser(NewTestParser(input));
43
44 EXPECT_EQ('H', *parser->pos());
45 for (size_t i = 1; i < input.length(); ++i) {
46 parser->ConsumeChar();
47 EXPECT_EQ(input[i], *parser->PeekChar());
48 }
49 parser->ConsumeChar();
50 EXPECT_EQ('\0', *parser->pos());
51 EXPECT_EQ(static_cast<size_t>(parser->index_), parser->input_.length());
52 }
53
TEST_F(JSONParserTest,ConsumeString)54 TEST_F(JSONParserTest, ConsumeString) {
55 std::string input("\"test\",|");
56 std::unique_ptr<JSONParser> parser(NewTestParser(input));
57 std::optional<Value> value(parser->ConsumeString());
58 EXPECT_EQ(',', *parser->pos());
59
60 TestLastThree(parser.get());
61
62 ASSERT_TRUE(value);
63 ASSERT_TRUE(value->is_string());
64 EXPECT_EQ("test", value->GetString());
65 }
66
TEST_F(JSONParserTest,ConsumeList)67 TEST_F(JSONParserTest, ConsumeList) {
68 std::string input("[true, false],|");
69 std::unique_ptr<JSONParser> parser(NewTestParser(input));
70 std::optional<Value> value(parser->ConsumeList());
71 EXPECT_EQ(',', *parser->pos());
72
73 TestLastThree(parser.get());
74
75 ASSERT_TRUE(value);
76 Value::List* list = value->GetIfList();
77 ASSERT_TRUE(list);
78 EXPECT_EQ(2u, list->size());
79 }
80
TEST_F(JSONParserTest,ConsumeDictionary)81 TEST_F(JSONParserTest, ConsumeDictionary) {
82 std::string input("{\"abc\":\"def\"},|");
83 std::unique_ptr<JSONParser> parser(NewTestParser(input));
84 std::optional<Value> value(parser->ConsumeDictionary());
85 EXPECT_EQ(',', *parser->pos());
86
87 TestLastThree(parser.get());
88
89 ASSERT_TRUE(value);
90 const Value::Dict* value_dict = value->GetIfDict();
91 ASSERT_TRUE(value_dict);
92 const std::string* str = value_dict->FindString("abc");
93 ASSERT_TRUE(str);
94 EXPECT_EQ("def", *str);
95 }
96
TEST_F(JSONParserTest,ConsumeLiterals)97 TEST_F(JSONParserTest, ConsumeLiterals) {
98 // Literal |true|.
99 std::string input("true,|");
100 std::unique_ptr<JSONParser> parser(NewTestParser(input));
101 std::optional<Value> value(parser->ConsumeLiteral());
102 EXPECT_EQ(',', *parser->pos());
103
104 TestLastThree(parser.get());
105
106 ASSERT_TRUE(value);
107 ASSERT_TRUE(value->is_bool());
108 EXPECT_TRUE(value->GetBool());
109
110 // Literal |false|.
111 input = "false,|";
112 parser.reset(NewTestParser(input));
113 value = parser->ConsumeLiteral();
114 EXPECT_EQ(',', *parser->pos());
115
116 TestLastThree(parser.get());
117
118 ASSERT_TRUE(value);
119 ASSERT_TRUE(value->is_bool());
120 EXPECT_FALSE(value->GetBool());
121
122 // Literal |null|.
123 input = "null,|";
124 parser.reset(NewTestParser(input));
125 value = parser->ConsumeLiteral();
126 EXPECT_EQ(',', *parser->pos());
127
128 TestLastThree(parser.get());
129
130 ASSERT_TRUE(value);
131 EXPECT_TRUE(value->is_none());
132 }
133
TEST_F(JSONParserTest,ConsumeNumbers)134 TEST_F(JSONParserTest, ConsumeNumbers) {
135 // Integer.
136 std::string input("1234,|");
137 std::unique_ptr<JSONParser> parser(NewTestParser(input));
138 std::optional<Value> value(parser->ConsumeNumber());
139 EXPECT_EQ(',', *parser->pos());
140
141 TestLastThree(parser.get());
142
143 ASSERT_TRUE(value);
144 ASSERT_TRUE(value->is_int());
145 EXPECT_EQ(1234, value->GetInt());
146
147 // Negative integer.
148 input = "-1234,|";
149 parser.reset(NewTestParser(input));
150 value = parser->ConsumeNumber();
151 EXPECT_EQ(',', *parser->pos());
152
153 TestLastThree(parser.get());
154
155 ASSERT_TRUE(value);
156 ASSERT_TRUE(value->is_int());
157 EXPECT_EQ(-1234, value->GetInt());
158
159 // Negative zero integer.
160 input = "-0,|";
161 parser.reset(NewTestParser(input));
162 value = parser->ConsumeNumber();
163 EXPECT_EQ(',', *parser->pos());
164
165 TestLastThree(parser.get());
166
167 ASSERT_TRUE(value);
168 ASSERT_TRUE(value->is_double());
169 EXPECT_EQ(-0.0, value->GetDouble());
170
171 // Double.
172 input = "12.34,|";
173 parser.reset(NewTestParser(input));
174 value = parser->ConsumeNumber();
175 EXPECT_EQ(',', *parser->pos());
176
177 TestLastThree(parser.get());
178
179 ASSERT_TRUE(value);
180 ASSERT_TRUE(value->is_double());
181 EXPECT_EQ(12.34, value->GetDouble());
182
183 // Negative zero double.
184 input = "-0.0,|";
185 parser.reset(NewTestParser(input));
186 value = parser->ConsumeNumber();
187 EXPECT_EQ(',', *parser->pos());
188
189 TestLastThree(parser.get());
190
191 ASSERT_TRUE(value);
192 ASSERT_TRUE(value->is_double());
193 EXPECT_EQ(-0.0, value->GetDouble());
194
195 // Scientific.
196 input = "42e3,|";
197 parser.reset(NewTestParser(input));
198 value = parser->ConsumeNumber();
199 EXPECT_EQ(',', *parser->pos());
200
201 TestLastThree(parser.get());
202
203 ASSERT_TRUE(value);
204 ASSERT_TRUE(value->is_double());
205 EXPECT_EQ(42000, value->GetDouble());
206
207 // Negative scientific.
208 input = "314159e-5,|";
209 parser.reset(NewTestParser(input));
210 value = parser->ConsumeNumber();
211 EXPECT_EQ(',', *parser->pos());
212
213 TestLastThree(parser.get());
214
215 ASSERT_TRUE(value);
216 ASSERT_TRUE(value->is_double());
217 EXPECT_EQ(3.14159, value->GetDouble());
218
219 // Positive scientific.
220 input = "0.42e+3,|";
221 parser.reset(NewTestParser(input));
222 value = parser->ConsumeNumber();
223 EXPECT_EQ(',', *parser->pos());
224
225 TestLastThree(parser.get());
226
227 ASSERT_TRUE(value);
228 ASSERT_TRUE(value->is_double());
229 EXPECT_EQ(420, value->GetDouble());
230 }
231
TEST_F(JSONParserTest,ErrorMessages)232 TEST_F(JSONParserTest, ErrorMessages) {
233 {
234 JSONParser parser(JSON_PARSE_RFC);
235 std::optional<Value> value = parser.Parse("[42]");
236 EXPECT_TRUE(value);
237 EXPECT_TRUE(parser.GetErrorMessage().empty());
238 EXPECT_EQ(0, parser.error_code());
239 }
240
241 // Test each of the error conditions
242 {
243 JSONParser parser(JSON_PARSE_RFC);
244 std::optional<Value> value = parser.Parse("{},{}");
245 EXPECT_FALSE(value);
246 EXPECT_EQ(JSONParser::FormatErrorMessage(
247 1, 3, JSONParser::kUnexpectedDataAfterRoot),
248 parser.GetErrorMessage());
249 EXPECT_EQ(JSONParser::JSON_UNEXPECTED_DATA_AFTER_ROOT, parser.error_code());
250 }
251
252 {
253 std::string nested_json;
254 for (int i = 0; i < 201; ++i) {
255 nested_json.insert(nested_json.begin(), '[');
256 nested_json.append(1, ']');
257 }
258 JSONParser parser(JSON_PARSE_RFC);
259 std::optional<Value> value = parser.Parse(nested_json);
260 EXPECT_FALSE(value);
261 EXPECT_EQ(
262 JSONParser::FormatErrorMessage(1, 200, JSONParser::kTooMuchNesting),
263 parser.GetErrorMessage());
264 EXPECT_EQ(JSONParser::JSON_TOO_MUCH_NESTING, parser.error_code());
265 }
266
267 {
268 JSONParser parser(JSON_PARSE_RFC);
269 std::optional<Value> value = parser.Parse("[1,]");
270 EXPECT_FALSE(value);
271 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 4, JSONParser::kTrailingComma),
272 parser.GetErrorMessage());
273 EXPECT_EQ(JSONParser::JSON_TRAILING_COMMA, parser.error_code());
274 }
275
276 {
277 JSONParser parser(JSON_PARSE_RFC);
278 std::optional<Value> value = parser.Parse("{foo:\"bar\"}");
279 EXPECT_FALSE(value);
280 EXPECT_EQ(JSONParser::FormatErrorMessage(
281 1, 2, JSONParser::kUnquotedDictionaryKey),
282 parser.GetErrorMessage());
283 EXPECT_EQ(JSONParser::JSON_UNQUOTED_DICTIONARY_KEY, parser.error_code());
284 }
285
286 {
287 JSONParser parser(JSON_PARSE_RFC);
288 std::optional<Value> value = parser.Parse("{\"foo\":\"bar\",}");
289 EXPECT_FALSE(value);
290 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 14, JSONParser::kTrailingComma),
291 parser.GetErrorMessage());
292 EXPECT_EQ(JSONParser::JSON_TRAILING_COMMA, parser.error_code());
293 }
294
295 {
296 JSONParser parser(JSON_PARSE_RFC);
297 std::optional<Value> value = parser.Parse("[nu]");
298 EXPECT_FALSE(value);
299 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2, JSONParser::kSyntaxError),
300 parser.GetErrorMessage());
301 EXPECT_EQ(JSONParser::JSON_SYNTAX_ERROR, parser.error_code());
302 }
303
304 {
305 JSONParser parser(JSON_PARSE_RFC | JSON_ALLOW_X_ESCAPES);
306 std::optional<Value> value = parser.Parse("[\"xxx\\xq\"]");
307 EXPECT_FALSE(value);
308 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
309 parser.GetErrorMessage());
310 EXPECT_EQ(JSONParser::JSON_INVALID_ESCAPE, parser.error_code());
311 }
312
313 {
314 JSONParser parser(JSON_PARSE_RFC);
315 std::optional<Value> value = parser.Parse("[\"xxx\\uq\"]");
316 EXPECT_FALSE(value);
317 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
318 parser.GetErrorMessage());
319 EXPECT_EQ(JSONParser::JSON_INVALID_ESCAPE, parser.error_code());
320 }
321
322 {
323 JSONParser parser(JSON_PARSE_RFC);
324 std::optional<Value> value = parser.Parse("[\"xxx\\q\"]");
325 EXPECT_FALSE(value);
326 EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
327 parser.GetErrorMessage());
328 EXPECT_EQ(JSONParser::JSON_INVALID_ESCAPE, parser.error_code());
329 }
330
331 {
332 JSONParser parser(JSON_PARSE_RFC);
333 std::optional<Value> value = parser.Parse("\"abc\ndef\"");
334 EXPECT_FALSE(value);
335 EXPECT_EQ(
336 JSONParser::FormatErrorMessage(1, 4, JSONParser::kUnsupportedEncoding),
337 parser.GetErrorMessage());
338 EXPECT_EQ(JSONParser::JSON_UNSUPPORTED_ENCODING, parser.error_code());
339 }
340 }
341
342 } // namespace internal
343 } // namespace base
344