blob: 7a2c16e7b585cce2d1eb7573614bb35455e52d7a [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include "testing/gtest/include/gtest/gtest.h"
6#include "base/json_reader.h"
7#include "base/values.h"
tc@google.comd3bb16f2008-08-09 02:26:42 +09008#include "build/build_config.h"
initial.commit3f4a7322008-07-27 06:49:38 +09009
10TEST(JSONReaderTest, Reading) {
11 // some whitespace checking
12 Value* root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090013 ASSERT_TRUE(JSONReader().JsonToValue(" null ", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090014 ASSERT_TRUE(root);
15 ASSERT_TRUE(root->IsType(Value::TYPE_NULL));
16 delete root;
17
18 // Invalid JSON string
19 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090020 ASSERT_FALSE(JSONReader().JsonToValue("nu", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090021 ASSERT_FALSE(root);
22
23 // Simple bool
24 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090025 ASSERT_TRUE(JSONReader().JsonToValue("true ", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090026 ASSERT_TRUE(root);
27 ASSERT_TRUE(root->IsType(Value::TYPE_BOOLEAN));
28 delete root;
29
30 // Test number formats
31 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090032 ASSERT_TRUE(JSONReader().JsonToValue("43", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090033 ASSERT_TRUE(root);
34 ASSERT_TRUE(root->IsType(Value::TYPE_INTEGER));
35 int int_val = 0;
36 ASSERT_TRUE(root->GetAsInteger(&int_val));
37 ASSERT_EQ(43, int_val);
38 delete root;
39
40 // According to RFC4627, oct, hex, and leading zeros are invalid JSON.
41 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090042 ASSERT_FALSE(JSONReader().JsonToValue("043", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090043 ASSERT_FALSE(root);
44 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090045 ASSERT_FALSE(JSONReader().JsonToValue("0x43", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090046 ASSERT_FALSE(root);
47 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090048 ASSERT_FALSE(JSONReader().JsonToValue("00", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090049 ASSERT_FALSE(root);
50
51 // Test 0 (which needs to be special cased because of the leading zero
52 // clause).
53 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090054 ASSERT_TRUE(JSONReader().JsonToValue("0", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090055 ASSERT_TRUE(root);
56 ASSERT_TRUE(root->IsType(Value::TYPE_INTEGER));
57 int_val = 1;
58 ASSERT_TRUE(root->GetAsInteger(&int_val));
59 ASSERT_EQ(0, int_val);
60 delete root;
61
mmentovai@google.com8dcf71c2008-08-08 02:15:41 +090062 // Numbers that overflow ints should succeed, being internally promoted to
63 // storage as doubles
initial.commit3f4a7322008-07-27 06:49:38 +090064 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090065 ASSERT_TRUE(JSONReader().JsonToValue("2147483648", &root, false, false));
mmentovai@google.com8dcf71c2008-08-08 02:15:41 +090066 ASSERT_TRUE(root);
tc@google.comd3bb16f2008-08-09 02:26:42 +090067 double real_val;
68#ifdef ARCH_CPU_32_BITS
69 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
70 real_val = 0.0;
71 ASSERT_TRUE(root->GetAsReal(&real_val));
72 ASSERT_DOUBLE_EQ(2147483648.0, real_val);
73#else
74 ASSERT_TRUE(root->IsType(Value::TYPE_INTEGER));
75 int_val = 0;
76 ASSERT_TRUE(root->GetAsInteger(&int_val));
77 ASSERT_EQ(2147483648, int_val);
78#endif
79 delete root;
initial.commit3f4a7322008-07-27 06:49:38 +090080 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090081 ASSERT_TRUE(JSONReader().JsonToValue("-2147483649", &root, false, false));
mmentovai@google.com8dcf71c2008-08-08 02:15:41 +090082 ASSERT_TRUE(root);
tc@google.comd3bb16f2008-08-09 02:26:42 +090083#ifdef ARCH_CPU_32_BITS
84 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
85 real_val = 0.0;
86 ASSERT_TRUE(root->GetAsReal(&real_val));
87 ASSERT_DOUBLE_EQ(-2147483649.0, real_val);
88#else
89 ASSERT_TRUE(root->IsType(Value::TYPE_INTEGER));
90 int_val = 0;
91 ASSERT_TRUE(root->GetAsInteger(&int_val));
92 ASSERT_EQ(-2147483649, int_val);
93#endif
94 delete root;
initial.commit3f4a7322008-07-27 06:49:38 +090095
96 // Parse a double
97 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +090098 ASSERT_TRUE(JSONReader().JsonToValue("43.1", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +090099 ASSERT_TRUE(root);
100 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
tc@google.comd3bb16f2008-08-09 02:26:42 +0900101 real_val = 0.0;
initial.commit3f4a7322008-07-27 06:49:38 +0900102 ASSERT_TRUE(root->GetAsReal(&real_val));
103 ASSERT_DOUBLE_EQ(43.1, real_val);
104 delete root;
105
106 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900107 ASSERT_TRUE(JSONReader().JsonToValue("4.3e-1", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900108 ASSERT_TRUE(root);
109 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
110 real_val = 0.0;
111 ASSERT_TRUE(root->GetAsReal(&real_val));
112 ASSERT_DOUBLE_EQ(.43, real_val);
113 delete root;
114
115 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900116 ASSERT_TRUE(JSONReader().JsonToValue("2.1e0", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900117 ASSERT_TRUE(root);
118 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
119 real_val = 0.0;
120 ASSERT_TRUE(root->GetAsReal(&real_val));
121 ASSERT_DOUBLE_EQ(2.1, real_val);
122 delete root;
123
124 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900125 ASSERT_TRUE(JSONReader().JsonToValue("2.1e+0001", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900126 ASSERT_TRUE(root);
127 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
128 real_val = 0.0;
129 ASSERT_TRUE(root->GetAsReal(&real_val));
130 ASSERT_DOUBLE_EQ(21.0, real_val);
131 delete root;
132
133 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900134 ASSERT_TRUE(JSONReader().JsonToValue("0.01", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900135 ASSERT_TRUE(root);
136 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
137 real_val = 0.0;
138 ASSERT_TRUE(root->GetAsReal(&real_val));
139 ASSERT_DOUBLE_EQ(0.01, real_val);
140 delete root;
141
142 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900143 ASSERT_TRUE(JSONReader().JsonToValue("1.00", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900144 ASSERT_TRUE(root);
145 ASSERT_TRUE(root->IsType(Value::TYPE_REAL));
146 real_val = 0.0;
147 ASSERT_TRUE(root->GetAsReal(&real_val));
148 ASSERT_DOUBLE_EQ(1.0, real_val);
149 delete root;
150
151 // Fractional parts must have a digit before and after the decimal point.
152 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900153 ASSERT_FALSE(JSONReader().JsonToValue("1.", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900154 ASSERT_FALSE(root);
155 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900156 ASSERT_FALSE(JSONReader().JsonToValue(".1", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900157 ASSERT_FALSE(root);
158 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900159 ASSERT_FALSE(JSONReader().JsonToValue("1.e10", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900160 ASSERT_FALSE(root);
161
162 // Exponent must have a digit following the 'e'.
163 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900164 ASSERT_FALSE(JSONReader().JsonToValue("1e", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900165 ASSERT_FALSE(root);
166 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900167 ASSERT_FALSE(JSONReader().JsonToValue("1E", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900168 ASSERT_FALSE(root);
169 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900170 ASSERT_FALSE(JSONReader().JsonToValue("1e1.", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900171 ASSERT_FALSE(root);
172 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900173 ASSERT_FALSE(JSONReader().JsonToValue("1e1.0", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900174 ASSERT_FALSE(root);
175
176 // INF/-INF/NaN are not valid
177 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900178 ASSERT_FALSE(JSONReader().JsonToValue("1e1000", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900179 ASSERT_FALSE(root);
180 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900181 ASSERT_FALSE(JSONReader().JsonToValue("-1e1000", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900182 ASSERT_FALSE(root);
183 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900184 ASSERT_FALSE(JSONReader().JsonToValue("NaN", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900185 ASSERT_FALSE(root);
tc@google.comfbc20492008-11-18 09:14:28 +0900186 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900187 ASSERT_FALSE(JSONReader().JsonToValue("nan", &root, false, false));
tc@google.comfbc20492008-11-18 09:14:28 +0900188 ASSERT_FALSE(root);
189 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900190 ASSERT_FALSE(JSONReader().JsonToValue("inf", &root, false, false));
tc@google.comfbc20492008-11-18 09:14:28 +0900191 ASSERT_FALSE(root);
initial.commit3f4a7322008-07-27 06:49:38 +0900192
193 // Invalid number formats
194 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900195 ASSERT_FALSE(JSONReader().JsonToValue("4.3.1", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900196 ASSERT_FALSE(root);
197 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900198 ASSERT_FALSE(JSONReader().JsonToValue("4e3.1", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900199 ASSERT_FALSE(root);
200
201 // Test string parser
202 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900203 ASSERT_TRUE(JSONReader().JsonToValue("\"hello world\"", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900204 ASSERT_TRUE(root);
205 ASSERT_TRUE(root->IsType(Value::TYPE_STRING));
206 std::wstring str_val;
207 ASSERT_TRUE(root->GetAsString(&str_val));
208 ASSERT_EQ(L"hello world", str_val);
209 delete root;
210
211 // Empty string
212 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900213 ASSERT_TRUE(JSONReader().JsonToValue("\"\"", &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900214 ASSERT_TRUE(root);
215 ASSERT_TRUE(root->IsType(Value::TYPE_STRING));
216 str_val.clear();
217 ASSERT_TRUE(root->GetAsString(&str_val));
218 ASSERT_EQ(L"", str_val);
219 delete root;
220
221 // Test basic string escapes
222 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900223 ASSERT_TRUE(JSONReader().JsonToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"",
224 &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900225 ASSERT_TRUE(root);
226 ASSERT_TRUE(root->IsType(Value::TYPE_STRING));
227 str_val.clear();
228 ASSERT_TRUE(root->GetAsString(&str_val));
sky@google.com0ba93512008-10-02 02:26:06 +0900229 ASSERT_EQ(L" \"\\/\b\f\n\r\t\v", str_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900230 delete root;
231
232 // Test hex and unicode escapes including the null character.
233 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900234 ASSERT_TRUE(JSONReader().JsonToValue("\"\\x41\\x00\\u1234\"", &root, false,
tc@google.comce6a78d2008-07-29 09:01:31 +0900235 false));
initial.commit3f4a7322008-07-27 06:49:38 +0900236 ASSERT_TRUE(root);
237 ASSERT_TRUE(root->IsType(Value::TYPE_STRING));
238 str_val.clear();
239 ASSERT_TRUE(root->GetAsString(&str_val));
240 ASSERT_EQ(std::wstring(L"A\0\x1234", 3), str_val);
241 delete root;
242
243 // Test invalid strings
244 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900245 ASSERT_FALSE(JSONReader().JsonToValue("\"no closing quote", &root, false,
tc@google.comce6a78d2008-07-29 09:01:31 +0900246 false));
initial.commit3f4a7322008-07-27 06:49:38 +0900247 ASSERT_FALSE(root);
248 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900249 ASSERT_FALSE(JSONReader().JsonToValue("\"\\z invalid escape char\"", &root,
tc@google.comce6a78d2008-07-29 09:01:31 +0900250 false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900251 ASSERT_FALSE(root);
252 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900253 ASSERT_FALSE(JSONReader().JsonToValue("\"\\xAQ invalid hex code\"", &root,
tc@google.comce6a78d2008-07-29 09:01:31 +0900254 false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900255 ASSERT_FALSE(root);
256 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900257 ASSERT_FALSE(JSONReader().JsonToValue("not enough hex chars\\x1\"", &root,
tc@google.comce6a78d2008-07-29 09:01:31 +0900258 false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900259 ASSERT_FALSE(root);
260 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900261 ASSERT_FALSE(JSONReader().JsonToValue("\"not enough escape chars\\u123\"",
tc@google.comce6a78d2008-07-29 09:01:31 +0900262 &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900263 ASSERT_FALSE(root);
264 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900265 ASSERT_FALSE(JSONReader().JsonToValue("\"extra backslash at end of input\\\"",
tc@google.comce6a78d2008-07-29 09:01:31 +0900266 &root, false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900267 ASSERT_FALSE(root);
268
269 // Basic array
270 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900271 ASSERT_TRUE(JSONReader::Read("[true, false, null]", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900272 ASSERT_TRUE(root);
273 ASSERT_TRUE(root->IsType(Value::TYPE_LIST));
274 ListValue* list = static_cast<ListValue*>(root);
darin@google.comf3272802008-08-15 05:27:29 +0900275 ASSERT_EQ(3U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900276
277 // Test with trailing comma. Should be parsed the same as above.
278 Value* root2 = NULL;
279 ASSERT_TRUE(JSONReader::Read("[true, false, null, ]", &root2, true));
280 EXPECT_TRUE(root->Equals(root2));
initial.commit3f4a7322008-07-27 06:49:38 +0900281 delete root;
tc@google.comce6a78d2008-07-29 09:01:31 +0900282 delete root2;
initial.commit3f4a7322008-07-27 06:49:38 +0900283
284 // Empty array
285 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900286 ASSERT_TRUE(JSONReader::Read("[]", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900287 ASSERT_TRUE(root);
288 ASSERT_TRUE(root->IsType(Value::TYPE_LIST));
289 list = static_cast<ListValue*>(root);
darin@google.comf3272802008-08-15 05:27:29 +0900290 ASSERT_EQ(0U, list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900291 delete root;
292
293 // Nested arrays
294 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900295 ASSERT_TRUE(JSONReader::Read("[[true], [], [false, [], [null]], null]", &root,
296 false));
initial.commit3f4a7322008-07-27 06:49:38 +0900297 ASSERT_TRUE(root);
298 ASSERT_TRUE(root->IsType(Value::TYPE_LIST));
299 list = static_cast<ListValue*>(root);
darin@google.comf3272802008-08-15 05:27:29 +0900300 ASSERT_EQ(4U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900301
302 // Lots of trailing commas.
303 root2 = NULL;
304 ASSERT_TRUE(JSONReader::Read("[[true], [], [false, [], [null, ] , ], null,]",
305 &root2, true));
306 EXPECT_TRUE(root->Equals(root2));
initial.commit3f4a7322008-07-27 06:49:38 +0900307 delete root;
tc@google.comce6a78d2008-07-29 09:01:31 +0900308 delete root2;
initial.commit3f4a7322008-07-27 06:49:38 +0900309
310 // Invalid, missing close brace.
311 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900312 ASSERT_FALSE(JSONReader::Read("[[true], [], [false, [], [null]], null", &root,
313 false));
initial.commit3f4a7322008-07-27 06:49:38 +0900314 ASSERT_FALSE(root);
315
316 // Invalid, too many commas
317 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900318 ASSERT_FALSE(JSONReader::Read("[true,, null]", &root, false));
319 ASSERT_FALSE(root);
320 ASSERT_FALSE(JSONReader::Read("[true,, null]", &root, true));
initial.commit3f4a7322008-07-27 06:49:38 +0900321 ASSERT_FALSE(root);
322
323 // Invalid, no commas
324 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900325 ASSERT_FALSE(JSONReader::Read("[true null]", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900326 ASSERT_FALSE(root);
327
328 // Invalid, trailing comma
329 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900330 ASSERT_FALSE(JSONReader::Read("[true,]", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900331 ASSERT_FALSE(root);
332
tc@google.comce6a78d2008-07-29 09:01:31 +0900333 // Valid if we set |allow_trailing_comma| to true.
334 EXPECT_TRUE(JSONReader::Read("[true,]", &root, true));
335 ASSERT_TRUE(root);
336 ASSERT_TRUE(root->IsType(Value::TYPE_LIST));
337 list = static_cast<ListValue*>(root);
darin@google.comf3272802008-08-15 05:27:29 +0900338 EXPECT_EQ(1U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900339 Value* tmp_value = NULL;
340 ASSERT_TRUE(list->Get(0, &tmp_value));
341 EXPECT_TRUE(tmp_value->IsType(Value::TYPE_BOOLEAN));
342 bool bool_value = false;
343 ASSERT_TRUE(tmp_value->GetAsBoolean(&bool_value));
344 EXPECT_TRUE(bool_value);
345 delete root;
346
347 // Don't allow empty elements, even if |allow_trailing_comma| is
348 // true.
349 root = NULL;
350 EXPECT_FALSE(JSONReader::Read("[,]", &root, true));
351 EXPECT_FALSE(root);
352 EXPECT_FALSE(JSONReader::Read("[true,,]", &root, true));
353 EXPECT_FALSE(root);
354 EXPECT_FALSE(JSONReader::Read("[,true,]", &root, true));
355 EXPECT_FALSE(root);
356 EXPECT_FALSE(JSONReader::Read("[true,,false]", &root, true));
357 EXPECT_FALSE(root);
358
initial.commit3f4a7322008-07-27 06:49:38 +0900359 // Test objects
360 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900361 ASSERT_TRUE(JSONReader::Read("{}", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900362 ASSERT_TRUE(root);
363 ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
364 delete root;
365
366 root = NULL;
367 ASSERT_TRUE(JSONReader::Read(
tc@google.comce6a78d2008-07-29 09:01:31 +0900368 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\" }", &root,
369 false));
initial.commit3f4a7322008-07-27 06:49:38 +0900370 ASSERT_TRUE(root);
371 ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
372 DictionaryValue* dict_val = static_cast<DictionaryValue*>(root);
373 real_val = 0.0;
374 ASSERT_TRUE(dict_val->GetReal(L"number", &real_val));
375 ASSERT_DOUBLE_EQ(9.87654321, real_val);
376 Value* null_val = NULL;
377 ASSERT_TRUE(dict_val->Get(L"null", &null_val));
378 ASSERT_TRUE(null_val->IsType(Value::TYPE_NULL));
379 str_val.clear();
380 ASSERT_TRUE(dict_val->GetString(L"S", &str_val));
381 ASSERT_EQ(L"str", str_val);
tc@google.comce6a78d2008-07-29 09:01:31 +0900382
383 root2 = NULL;
384 ASSERT_TRUE(JSONReader::Read(
385 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", }", &root2,
386 true));
387 EXPECT_TRUE(root->Equals(root2));
initial.commit3f4a7322008-07-27 06:49:38 +0900388 delete root;
tc@google.comce6a78d2008-07-29 09:01:31 +0900389 delete root2;
initial.commit3f4a7322008-07-27 06:49:38 +0900390
391 // Test nesting
392 root = NULL;
393 ASSERT_TRUE(JSONReader::Read(
tc@google.comce6a78d2008-07-29 09:01:31 +0900394 "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900395 ASSERT_TRUE(root);
396 ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
397 dict_val = static_cast<DictionaryValue*>(root);
398 DictionaryValue* inner_dict = NULL;
399 ASSERT_TRUE(dict_val->GetDictionary(L"inner", &inner_dict));
400 ListValue* inner_array = NULL;
401 ASSERT_TRUE(inner_dict->GetList(L"array", &inner_array));
darin@google.comf3272802008-08-15 05:27:29 +0900402 ASSERT_EQ(1U, inner_array->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900403 bool_value = true;
initial.commit3f4a7322008-07-27 06:49:38 +0900404 ASSERT_TRUE(dict_val->GetBoolean(L"false", &bool_value));
405 ASSERT_FALSE(bool_value);
406 inner_dict = NULL;
407 ASSERT_TRUE(dict_val->GetDictionary(L"d", &inner_dict));
tc@google.comce6a78d2008-07-29 09:01:31 +0900408
409 root2 = NULL;
410 ASSERT_TRUE(JSONReader::Read(
411 "{\"inner\": {\"array\":[true] , },\"false\":false,\"d\":{},}", &root2,
412 true));
413 EXPECT_TRUE(root->Equals(root2));
initial.commit3f4a7322008-07-27 06:49:38 +0900414 delete root;
tc@google.comce6a78d2008-07-29 09:01:31 +0900415 delete root2;
initial.commit3f4a7322008-07-27 06:49:38 +0900416
417 // Invalid, no closing brace
418 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900419 ASSERT_FALSE(JSONReader::Read("{\"a\": true", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900420 ASSERT_FALSE(root);
421
422 // Invalid, keys must be quoted
423 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900424 ASSERT_FALSE(JSONReader::Read("{foo:true}", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900425 ASSERT_FALSE(root);
426
427 // Invalid, trailing comma
428 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900429 ASSERT_FALSE(JSONReader::Read("{\"a\":true,}", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900430 ASSERT_FALSE(root);
431
432 // Invalid, too many commas
433 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900434 ASSERT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}", &root, false));
435 ASSERT_FALSE(root);
436 root = NULL;
437 ASSERT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}", &root, true));
initial.commit3f4a7322008-07-27 06:49:38 +0900438 ASSERT_FALSE(root);
439
440 // Invalid, no separator
441 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900442 ASSERT_FALSE(JSONReader::Read("{\"a\" \"b\"}", &root, false));
443 ASSERT_FALSE(root);
444
445 // Invalid, lone comma.
446 root = NULL;
447 ASSERT_FALSE(JSONReader::Read("{,}", &root, false));
448 ASSERT_FALSE(root);
449 ASSERT_FALSE(JSONReader::Read("{,}", &root, true));
450 ASSERT_FALSE(root);
451 ASSERT_FALSE(JSONReader::Read("{\"a\":true,,}", &root, true));
452 ASSERT_FALSE(root);
453 ASSERT_FALSE(JSONReader::Read("{,\"a\":true}", &root, true));
454 ASSERT_FALSE(root);
455 ASSERT_FALSE(JSONReader::Read("{\"a\":true,,\"b\":false}", &root, true));
initial.commit3f4a7322008-07-27 06:49:38 +0900456 ASSERT_FALSE(root);
457
458 // Test stack overflow
459 root = NULL;
460 std::string evil(1000000, '[');
461 evil.append(std::string(1000000, ']'));
tc@google.comce6a78d2008-07-29 09:01:31 +0900462 ASSERT_FALSE(JSONReader::Read(evil, &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900463 ASSERT_FALSE(root);
464
465 // A few thousand adjacent lists is fine.
466 std::string not_evil("[");
467 not_evil.reserve(15010);
468 for (int i = 0; i < 5000; ++i) {
469 not_evil.append("[],");
470 }
471 not_evil.append("[]]");
tc@google.comce6a78d2008-07-29 09:01:31 +0900472 ASSERT_TRUE(JSONReader::Read(not_evil, &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900473 ASSERT_TRUE(root);
474 ASSERT_TRUE(root->IsType(Value::TYPE_LIST));
475 list = static_cast<ListValue*>(root);
darin@google.comf3272802008-08-15 05:27:29 +0900476 ASSERT_EQ(5001U, list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900477 delete root;
478
479 // Test utf8 encoded input
480 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900481 ASSERT_TRUE(JSONReader().JsonToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\"", &root,
tc@google.comce6a78d2008-07-29 09:01:31 +0900482 false, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900483 ASSERT_TRUE(root);
484 ASSERT_TRUE(root->IsType(Value::TYPE_STRING));
485 str_val.clear();
486 ASSERT_TRUE(root->GetAsString(&str_val));
487 ASSERT_EQ(L"\x7f51\x9875", str_val);
488 delete root;
489
jungshik@google.com37790f32008-09-26 06:42:00 +0900490 // Test invalid utf8 encoded input
491 root = NULL;
aa@chromium.org971901c2008-12-06 07:14:46 +0900492 ASSERT_FALSE(JSONReader().JsonToValue("\"345\xb0\xa1\xb0\xa2\"", &root,
jungshik@google.com37790f32008-09-26 06:42:00 +0900493 false, false));
aa@chromium.org971901c2008-12-06 07:14:46 +0900494 ASSERT_FALSE(JSONReader().JsonToValue("\"123\xc0\x81\"", &root,
jungshik@google.com37790f32008-09-26 06:42:00 +0900495 false, false));
496
initial.commit3f4a7322008-07-27 06:49:38 +0900497 // Test invalid root objects.
498 root = NULL;
tc@google.comce6a78d2008-07-29 09:01:31 +0900499 ASSERT_FALSE(JSONReader::Read("null", &root, false));
500 ASSERT_FALSE(JSONReader::Read("true", &root, false));
501 ASSERT_FALSE(JSONReader::Read("10", &root, false));
502 ASSERT_FALSE(JSONReader::Read("\"root\"", &root, false));
initial.commit3f4a7322008-07-27 06:49:38 +0900503}
aa@chromium.org971901c2008-12-06 07:14:46 +0900504
505TEST(JSONReaderTest, ErrorMessages) {
506 // Error strings should not be modified in case of success.
507 std::string error_message;
508 Value* root = NULL;
509 ASSERT_TRUE(JSONReader::ReadAndReturnError("[42]", &root, false,
510 &error_message));
511 ASSERT_TRUE(error_message.empty());
512
513 // Test line and column counting
514 const char* big_json = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]";
515 // error here --------------------------------^
516 ASSERT_FALSE(JSONReader::ReadAndReturnError(big_json, &root, false,
517 &error_message));
518 ASSERT_EQ(JSONReader::FormatErrorMessage(5, 9, JSONReader::kSyntaxError),
519 error_message);
520
521 // Test each of the error conditions
522 ASSERT_FALSE(JSONReader::ReadAndReturnError("{},{}", &root, false,
523 &error_message));
524 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 3,
525 JSONReader::kUnexpectedDataAfterRoot), error_message);
526
527 std::string nested_json;
528 for (int i = 0; i < 101; ++i) {
529 nested_json.insert(nested_json.begin(), '[');
530 nested_json.append(1, ']');
531 }
532 ASSERT_FALSE(JSONReader::ReadAndReturnError(nested_json, &root, false,
533 &error_message));
534 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 101, JSONReader::kTooMuchNesting),
535 error_message);
536
537 ASSERT_FALSE(JSONReader::ReadAndReturnError("42", &root, false,
538 &error_message));
539 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 1,
540 JSONReader::kBadRootElementType), error_message);
541
542 ASSERT_FALSE(JSONReader::ReadAndReturnError("[1,]", &root, false,
543 &error_message));
544 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 4, JSONReader::kTrailingComma),
545 error_message);
546
547 ASSERT_FALSE(JSONReader::ReadAndReturnError("{foo:\"bar\"}", &root, false,
548 &error_message));
549 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 2,
550 JSONReader::kUnquotedDictionaryKey), error_message);
551
552 ASSERT_FALSE(JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}", &root,
553 false, &error_message));
554 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 14, JSONReader::kTrailingComma),
555 error_message);
556
557 ASSERT_FALSE(JSONReader::ReadAndReturnError("[nu]", &root, false,
558 &error_message));
559 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 2, JSONReader::kSyntaxError),
560 error_message);
561
562 ASSERT_FALSE(JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", &root, false,
563 &error_message));
564 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
565 error_message);
566
567 ASSERT_FALSE(JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", &root, false,
568 &error_message));
569 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
570 error_message);
571
572 ASSERT_FALSE(JSONReader::ReadAndReturnError("[\"xxx\\q\"]", &root, false,
573 &error_message));
574 ASSERT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
575 error_message);
576}