blob: 4d6b0c4edf595103a5bec62138c1a9d4586ae26a [file] [log] [blame]
rsesek@chromium.org284387b2012-03-21 07:21:49 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botf003cfe2008-08-24 09:55:55 +09002// 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
brettw@chromium.org7cd41eb2009-10-24 05:00:20 +09005#include "base/json/json_reader.h"
rsesek@chromium.org284387b2012-03-21 07:21:49 +09006
rsesek@chromium.orga37c6162012-03-28 13:54:44 +09007#include "base/base_paths.h"
8#include "base/file_util.h"
levin@chromium.org5c528682011-03-28 10:54:15 +09009#include "base/memory/scoped_ptr.h"
rsesek@chromium.orga37c6162012-03-28 13:54:44 +090010#include "base/path_service.h"
viettrungluu@chromium.org68354652010-08-16 16:13:53 +090011#include "base/string_piece.h"
12#include "base/utf_string_conversions.h"
initial.commit3f4a7322008-07-27 06:49:38 +090013#include "base/values.h"
tc@google.comd3bb16f2008-08-09 02:26:42 +090014#include "build/build_config.h"
rsesek@chromium.orga37c6162012-03-28 13:54:44 +090015#include "testing/gtest/include/gtest/gtest.h"
initial.commit3f4a7322008-07-27 06:49:38 +090016
brettw@chromium.org7cd41eb2009-10-24 05:00:20 +090017namespace base {
18
initial.commit3f4a7322008-07-27 06:49:38 +090019TEST(JSONReaderTest, Reading) {
20 // some whitespace checking
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090021 scoped_ptr<Value> root;
22 root.reset(JSONReader().JsonToValue(" null ", false, false));
23 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090024 EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
initial.commit3f4a7322008-07-27 06:49:38 +090025
26 // Invalid JSON string
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090027 root.reset(JSONReader().JsonToValue("nu", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +090028 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +090029
30 // Simple bool
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090031 root.reset(JSONReader().JsonToValue("true ", false, false));
32 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090033 EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN));
initial.commit3f4a7322008-07-27 06:49:38 +090034
munjal@chromium.org124260d2009-07-24 06:34:40 +090035 // Embedded comment
36 root.reset(JSONReader().JsonToValue("/* comment */null", false, false));
37 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090038 EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
munjal@chromium.org124260d2009-07-24 06:34:40 +090039 root.reset(JSONReader().JsonToValue("40 /* comment */", false, false));
40 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090041 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
munjal@chromium.org124260d2009-07-24 06:34:40 +090042 root.reset(JSONReader().JsonToValue("true // comment", false, false));
43 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090044 EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN));
munjal@chromium.org124260d2009-07-24 06:34:40 +090045 root.reset(JSONReader().JsonToValue("/* comment */\"sample string\"",
46 false, false));
47 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090048 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
munjal@chromium.org124260d2009-07-24 06:34:40 +090049 std::string value;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090050 EXPECT_TRUE(root->GetAsString(&value));
51 EXPECT_EQ("sample string", value);
munjal@chromium.org124260d2009-07-24 06:34:40 +090052
initial.commit3f4a7322008-07-27 06:49:38 +090053 // Test number formats
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090054 root.reset(JSONReader().JsonToValue("43", false, false));
55 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090056 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
initial.commit3f4a7322008-07-27 06:49:38 +090057 int int_val = 0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090058 EXPECT_TRUE(root->GetAsInteger(&int_val));
59 EXPECT_EQ(43, int_val);
initial.commit3f4a7322008-07-27 06:49:38 +090060
61 // According to RFC4627, oct, hex, and leading zeros are invalid JSON.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090062 root.reset(JSONReader().JsonToValue("043", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +090063 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090064 root.reset(JSONReader().JsonToValue("0x43", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +090065 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090066 root.reset(JSONReader().JsonToValue("00", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +090067 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +090068
69 // Test 0 (which needs to be special cased because of the leading zero
70 // clause).
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090071 root.reset(JSONReader().JsonToValue("0", false, false));
72 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090073 EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER));
initial.commit3f4a7322008-07-27 06:49:38 +090074 int_val = 1;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090075 EXPECT_TRUE(root->GetAsInteger(&int_val));
76 EXPECT_EQ(0, int_val);
initial.commit3f4a7322008-07-27 06:49:38 +090077
mmentovai@google.com8dcf71c2008-08-08 02:15:41 +090078 // Numbers that overflow ints should succeed, being internally promoted to
79 // storage as doubles
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090080 root.reset(JSONReader().JsonToValue("2147483648", false, false));
81 ASSERT_TRUE(root.get());
arv@chromium.org13413eb2011-02-01 10:02:07 +090082 double double_val;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090083 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +090084 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090085 EXPECT_TRUE(root->GetAsDouble(&double_val));
86 EXPECT_DOUBLE_EQ(2147483648.0, double_val);
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090087 root.reset(JSONReader().JsonToValue("-2147483649", false, false));
88 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090089 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +090090 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090091 EXPECT_TRUE(root->GetAsDouble(&double_val));
92 EXPECT_DOUBLE_EQ(-2147483649.0, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +090093
94 // Parse a double
aa@chromium.orgca9c79e2008-12-30 04:59:08 +090095 root.reset(JSONReader().JsonToValue("43.1", false, false));
96 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +090097 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +090098 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +090099 EXPECT_TRUE(root->GetAsDouble(&double_val));
100 EXPECT_DOUBLE_EQ(43.1, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900101
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900102 root.reset(JSONReader().JsonToValue("4.3e-1", false, false));
103 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900104 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +0900105 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900106 EXPECT_TRUE(root->GetAsDouble(&double_val));
107 EXPECT_DOUBLE_EQ(.43, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900108
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900109 root.reset(JSONReader().JsonToValue("2.1e0", false, false));
110 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900111 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +0900112 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900113 EXPECT_TRUE(root->GetAsDouble(&double_val));
114 EXPECT_DOUBLE_EQ(2.1, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900115
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900116 root.reset(JSONReader().JsonToValue("2.1e+0001", false, false));
117 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900118 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +0900119 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900120 EXPECT_TRUE(root->GetAsDouble(&double_val));
121 EXPECT_DOUBLE_EQ(21.0, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900122
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900123 root.reset(JSONReader().JsonToValue("0.01", false, false));
124 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900125 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +0900126 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900127 EXPECT_TRUE(root->GetAsDouble(&double_val));
128 EXPECT_DOUBLE_EQ(0.01, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900129
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900130 root.reset(JSONReader().JsonToValue("1.00", false, false));
131 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900132 EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE));
arv@chromium.org13413eb2011-02-01 10:02:07 +0900133 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900134 EXPECT_TRUE(root->GetAsDouble(&double_val));
135 EXPECT_DOUBLE_EQ(1.0, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900136
137 // Fractional parts must have a digit before and after the decimal point.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900138 root.reset(JSONReader().JsonToValue("1.", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900139 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900140 root.reset(JSONReader().JsonToValue(".1", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900141 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900142 root.reset(JSONReader().JsonToValue("1.e10", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900143 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900144
145 // Exponent must have a digit following the 'e'.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900146 root.reset(JSONReader().JsonToValue("1e", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900147 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900148 root.reset(JSONReader().JsonToValue("1E", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900149 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900150 root.reset(JSONReader().JsonToValue("1e1.", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900151 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900152 root.reset(JSONReader().JsonToValue("1e1.0", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900153 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900154
155 // INF/-INF/NaN are not valid
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900156 root.reset(JSONReader().JsonToValue("1e1000", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900157 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900158 root.reset(JSONReader().JsonToValue("-1e1000", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900159 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900160 root.reset(JSONReader().JsonToValue("NaN", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900161 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900162 root.reset(JSONReader().JsonToValue("nan", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900163 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900164 root.reset(JSONReader().JsonToValue("inf", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900165 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900166
167 // Invalid number formats
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900168 root.reset(JSONReader().JsonToValue("4.3.1", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900169 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900170 root.reset(JSONReader().JsonToValue("4e3.1", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900171 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900172
173 // Test string parser
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900174 root.reset(JSONReader().JsonToValue("\"hello world\"", false, false));
175 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900176 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
viettrungluu@chromium.org68354652010-08-16 16:13:53 +0900177 std::string str_val;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900178 EXPECT_TRUE(root->GetAsString(&str_val));
179 EXPECT_EQ("hello world", str_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900180
181 // Empty string
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900182 root.reset(JSONReader().JsonToValue("\"\"", false, false));
183 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900184 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
initial.commit3f4a7322008-07-27 06:49:38 +0900185 str_val.clear();
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900186 EXPECT_TRUE(root->GetAsString(&str_val));
187 EXPECT_EQ("", str_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900188
189 // Test basic string escapes
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900190 root.reset(JSONReader().JsonToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"",
191 false, false));
192 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900193 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
initial.commit3f4a7322008-07-27 06:49:38 +0900194 str_val.clear();
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900195 EXPECT_TRUE(root->GetAsString(&str_val));
196 EXPECT_EQ(" \"\\/\b\f\n\r\t\v", str_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900197
198 // Test hex and unicode escapes including the null character.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900199 root.reset(JSONReader().JsonToValue("\"\\x41\\x00\\u1234\"", false,
tc@google.comce6a78d2008-07-29 09:01:31 +0900200 false));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900201 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900202 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
initial.commit3f4a7322008-07-27 06:49:38 +0900203 str_val.clear();
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900204 EXPECT_TRUE(root->GetAsString(&str_val));
205 EXPECT_EQ(std::wstring(L"A\0\x1234", 3), UTF8ToWide(str_val));
initial.commit3f4a7322008-07-27 06:49:38 +0900206
207 // Test invalid strings
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900208 root.reset(JSONReader().JsonToValue("\"no closing quote", false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900209 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900210 root.reset(JSONReader().JsonToValue("\"\\z invalid escape char\"", false,
211 false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900212 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900213 root.reset(JSONReader().JsonToValue("\"\\xAQ invalid hex code\"", false,
214 false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900215 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900216 root.reset(JSONReader().JsonToValue("not enough hex chars\\x1\"", false,
217 false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900218 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900219 root.reset(JSONReader().JsonToValue("\"not enough escape chars\\u123\"",
220 false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900221 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900222 root.reset(JSONReader().JsonToValue("\"extra backslash at end of input\\\"",
223 false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900224 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900225
226 // Basic array
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900227 root.reset(JSONReader::Read("[true, false, null]"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900228 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900229 EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900230 ListValue* list = static_cast<ListValue*>(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900231 EXPECT_EQ(3U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900232
233 // Test with trailing comma. Should be parsed the same as above.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900234 scoped_ptr<Value> root2;
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900235 root2.reset(JSONReader::Read("[true, false, null, ]",
236 JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900237 EXPECT_TRUE(root->Equals(root2.get()));
initial.commit3f4a7322008-07-27 06:49:38 +0900238
239 // Empty array
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900240 root.reset(JSONReader::Read("[]"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900241 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900242 EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900243 list = static_cast<ListValue*>(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900244 EXPECT_EQ(0U, list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900245
246 // Nested arrays
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900247 root.reset(JSONReader::Read("[[true], [], [false, [], [null]], null]"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900248 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900249 EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900250 list = static_cast<ListValue*>(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900251 EXPECT_EQ(4U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900252
253 // Lots of trailing commas.
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900254 root2.reset(JSONReader::Read("[[true], [], [false, [], [null, ] , ], null,]",
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900255 JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900256 EXPECT_TRUE(root->Equals(root2.get()));
initial.commit3f4a7322008-07-27 06:49:38 +0900257
258 // Invalid, missing close brace.
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900259 root.reset(JSONReader::Read("[[true], [], [false, [], [null]], null"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900260 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900261
262 // Invalid, too many commas
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900263 root.reset(JSONReader::Read("[true,, null]"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900264 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900265 root.reset(JSONReader::Read("[true,, null]", JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900266 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900267
268 // Invalid, no commas
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900269 root.reset(JSONReader::Read("[true null]"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900270 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900271
272 // Invalid, trailing comma
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900273 root.reset(JSONReader::Read("[true,]"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900274 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900275
tc@google.comce6a78d2008-07-29 09:01:31 +0900276 // Valid if we set |allow_trailing_comma| to true.
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900277 root.reset(JSONReader::Read("[true,]", JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900278 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900279 EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900280 list = static_cast<ListValue*>(root.get());
darin@google.comf3272802008-08-15 05:27:29 +0900281 EXPECT_EQ(1U, list->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900282 Value* tmp_value = NULL;
283 ASSERT_TRUE(list->Get(0, &tmp_value));
284 EXPECT_TRUE(tmp_value->IsType(Value::TYPE_BOOLEAN));
285 bool bool_value = false;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900286 EXPECT_TRUE(tmp_value->GetAsBoolean(&bool_value));
tc@google.comce6a78d2008-07-29 09:01:31 +0900287 EXPECT_TRUE(bool_value);
tc@google.comce6a78d2008-07-29 09:01:31 +0900288
289 // Don't allow empty elements, even if |allow_trailing_comma| is
290 // true.
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900291 root.reset(JSONReader::Read("[,]", JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900292 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900293 root.reset(JSONReader::Read("[true,,]", JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900294 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900295 root.reset(JSONReader::Read("[,true,]", JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900296 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900297 root.reset(JSONReader::Read("[true,,false]", JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900298 EXPECT_FALSE(root.get());
tc@google.comce6a78d2008-07-29 09:01:31 +0900299
initial.commit3f4a7322008-07-27 06:49:38 +0900300 // Test objects
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900301 root.reset(JSONReader::Read("{}"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900302 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900303 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
initial.commit3f4a7322008-07-27 06:49:38 +0900304
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900305 root.reset(JSONReader::Read(
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900306 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\" }"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900307 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900308 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900309 DictionaryValue* dict_val = static_cast<DictionaryValue*>(root.get());
arv@chromium.org13413eb2011-02-01 10:02:07 +0900310 double_val = 0.0;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900311 EXPECT_TRUE(dict_val->GetDouble("number", &double_val));
312 EXPECT_DOUBLE_EQ(9.87654321, double_val);
initial.commit3f4a7322008-07-27 06:49:38 +0900313 Value* null_val = NULL;
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900314 ASSERT_TRUE(dict_val->Get("null", &null_val));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900315 EXPECT_TRUE(null_val->IsType(Value::TYPE_NULL));
nsylvain@chromium.org12426672009-03-04 07:59:43 +0900316 str_val.clear();
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900317 EXPECT_TRUE(dict_val->GetString("S", &str_val));
318 EXPECT_EQ("str", str_val);
tc@google.comce6a78d2008-07-29 09:01:31 +0900319
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900320 root2.reset(JSONReader::Read(
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900321 "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", }",
322 JSON_ALLOW_TRAILING_COMMAS));
mark@chromium.org95c9ec92009-06-27 06:17:24 +0900323 ASSERT_TRUE(root2.get());
324 EXPECT_TRUE(root->Equals(root2.get()));
325
326 // Test newline equivalence.
327 root2.reset(JSONReader::Read(
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900328 "{\n"
329 " \"number\":9.87654321,\n"
330 " \"null\":null,\n"
331 " \"\\x53\":\"str\",\n"
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900332 "}\n", JSON_ALLOW_TRAILING_COMMAS));
mark@chromium.org95c9ec92009-06-27 06:17:24 +0900333 ASSERT_TRUE(root2.get());
334 EXPECT_TRUE(root->Equals(root2.get()));
335
336 root2.reset(JSONReader::Read(
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900337 "{\r\n"
338 " \"number\":9.87654321,\r\n"
339 " \"null\":null,\r\n"
340 " \"\\x53\":\"str\",\r\n"
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900341 "}\r\n", JSON_ALLOW_TRAILING_COMMAS));
mark@chromium.org95c9ec92009-06-27 06:17:24 +0900342 ASSERT_TRUE(root2.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900343 EXPECT_TRUE(root->Equals(root2.get()));
initial.commit3f4a7322008-07-27 06:49:38 +0900344
345 // Test nesting
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900346 root.reset(JSONReader::Read(
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900347 "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}"));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900348 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900349 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900350 dict_val = static_cast<DictionaryValue*>(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900351 DictionaryValue* inner_dict = NULL;
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900352 ASSERT_TRUE(dict_val->GetDictionary("inner", &inner_dict));
initial.commit3f4a7322008-07-27 06:49:38 +0900353 ListValue* inner_array = NULL;
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900354 ASSERT_TRUE(inner_dict->GetList("array", &inner_array));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900355 EXPECT_EQ(1U, inner_array->GetSize());
tc@google.comce6a78d2008-07-29 09:01:31 +0900356 bool_value = true;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900357 EXPECT_TRUE(dict_val->GetBoolean("false", &bool_value));
358 EXPECT_FALSE(bool_value);
initial.commit3f4a7322008-07-27 06:49:38 +0900359 inner_dict = NULL;
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900360 EXPECT_TRUE(dict_val->GetDictionary("d", &inner_dict));
tc@google.comce6a78d2008-07-29 09:01:31 +0900361
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900362 root2.reset(JSONReader::Read(
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900363 "{\"inner\": {\"array\":[true] , },\"false\":false,\"d\":{},}",
364 JSON_ALLOW_TRAILING_COMMAS));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900365 EXPECT_TRUE(root->Equals(root2.get()));
initial.commit3f4a7322008-07-27 06:49:38 +0900366
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900367 // Test keys with periods
368 root.reset(JSONReader::Read(
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900369 "{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}"));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900370 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900371 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900372 dict_val = static_cast<DictionaryValue*>(root.get());
373 int integer_value = 0;
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900374 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("a.b", &integer_value));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900375 EXPECT_EQ(3, integer_value);
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900376 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("c", &integer_value));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900377 EXPECT_EQ(2, integer_value);
378 inner_dict = NULL;
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900379 ASSERT_TRUE(dict_val->GetDictionaryWithoutPathExpansion("d.e.f",
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900380 &inner_dict));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900381 EXPECT_EQ(1U, inner_dict->size());
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900382 EXPECT_TRUE(inner_dict->GetIntegerWithoutPathExpansion("g.h.i.j",
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900383 &integer_value));
384 EXPECT_EQ(1, integer_value);
385
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900386 root.reset(JSONReader::Read("{\"a\":{\"b\":2},\"a.b\":1}"));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900387 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900388 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900389 dict_val = static_cast<DictionaryValue*>(root.get());
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900390 EXPECT_TRUE(dict_val->GetInteger("a.b", &integer_value));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900391 EXPECT_EQ(2, integer_value);
viettrungluu@chromium.org4603a8d2010-08-14 10:49:14 +0900392 EXPECT_TRUE(dict_val->GetIntegerWithoutPathExpansion("a.b", &integer_value));
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900393 EXPECT_EQ(1, integer_value);
394
initial.commit3f4a7322008-07-27 06:49:38 +0900395 // Invalid, no closing brace
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900396 root.reset(JSONReader::Read("{\"a\": true"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900397 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900398
399 // Invalid, keys must be quoted
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900400 root.reset(JSONReader::Read("{foo:true}"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900401 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900402
403 // Invalid, trailing comma
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900404 root.reset(JSONReader::Read("{\"a\":true,}"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900405 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900406
407 // Invalid, too many commas
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900408 root.reset(JSONReader::Read("{\"a\":true,,\"b\":false}"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900409 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900410 root.reset(JSONReader::Read("{\"a\":true,,\"b\":false}",
411 JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900412 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900413
414 // Invalid, no separator
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900415 root.reset(JSONReader::Read("{\"a\" \"b\"}"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900416 EXPECT_FALSE(root.get());
tc@google.comce6a78d2008-07-29 09:01:31 +0900417
418 // Invalid, lone comma.
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900419 root.reset(JSONReader::Read("{,}"));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900420 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900421 root.reset(JSONReader::Read("{,}", JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900422 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900423 root.reset(JSONReader::Read("{\"a\":true,,}", JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900424 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900425 root.reset(JSONReader::Read("{,\"a\":true}", JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900426 EXPECT_FALSE(root.get());
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900427 root.reset(JSONReader::Read("{\"a\":true,,\"b\":false}",
428 JSON_ALLOW_TRAILING_COMMAS));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900429 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900430
431 // Test stack overflow
initial.commit3f4a7322008-07-27 06:49:38 +0900432 std::string evil(1000000, '[');
433 evil.append(std::string(1000000, ']'));
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900434 root.reset(JSONReader::Read(evil));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900435 EXPECT_FALSE(root.get());
initial.commit3f4a7322008-07-27 06:49:38 +0900436
437 // A few thousand adjacent lists is fine.
438 std::string not_evil("[");
439 not_evil.reserve(15010);
440 for (int i = 0; i < 5000; ++i) {
441 not_evil.append("[],");
442 }
443 not_evil.append("[]]");
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900444 root.reset(JSONReader::Read(not_evil));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900445 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900446 EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
stevenjb@google.comf4f58272011-08-26 10:54:00 +0900447 list = static_cast<ListValue*>(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900448 EXPECT_EQ(5001U, list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900449
450 // Test utf8 encoded input
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900451 root.reset(JSONReader().JsonToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\"",
tc@google.comce6a78d2008-07-29 09:01:31 +0900452 false, false));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900453 ASSERT_TRUE(root.get());
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900454 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
initial.commit3f4a7322008-07-27 06:49:38 +0900455 str_val.clear();
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900456 EXPECT_TRUE(root->GetAsString(&str_val));
457 EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val));
initial.commit3f4a7322008-07-27 06:49:38 +0900458
jungshik@google.com37790f32008-09-26 06:42:00 +0900459 // Test invalid utf8 encoded input
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900460 root.reset(JSONReader().JsonToValue("\"345\xb0\xa1\xb0\xa2\"",
461 false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900462 EXPECT_FALSE(root.get());
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900463 root.reset(JSONReader().JsonToValue("\"123\xc0\x81\"",
464 false, false));
rsesek@chromium.org284387b2012-03-21 07:21:49 +0900465 EXPECT_FALSE(root.get());
jungshik@google.com37790f32008-09-26 06:42:00 +0900466
rsesek@chromium.org125e8992012-03-24 12:57:17 +0900467 // Test utf16 encoded strings.
468 root.reset(JSONReader().JsonToValue("\"\\u20ac3,14\"", false, false));
469 ASSERT_TRUE(root.get());
470 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
471 str_val.clear();
472 EXPECT_TRUE(root->GetAsString(&str_val));
473 EXPECT_EQ("\xe2\x82\xac""3,14", str_val);
474
475 root.reset(JSONReader().JsonToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\"",
476 false, false));
477 ASSERT_TRUE(root.get());
478 EXPECT_TRUE(root->IsType(Value::TYPE_STRING));
479 str_val.clear();
480 EXPECT_TRUE(root->GetAsString(&str_val));
481 EXPECT_EQ("\xf0\x9f\x92\xa9\xf0\x9f\x91\xac", str_val);
482
483 // Test invalid utf16 strings.
484 const char* cases[] = {
485 "\"\\u123\"", // Invalid scalar.
486 "\"\\ud83d\"", // Invalid scalar.
487 "\"\\u$%@!\"", // Invalid scalar.
488 "\"\\uzz89\"", // Invalid scalar.
489 "\"\\ud83d\\udca\"", // Invalid lower surrogate.
490 "\"\\ud83d\\ud83d\"", // Invalid lower surrogate.
491 "\"\\ud83foo\"", // No lower surrogate.
492 "\"\\ud83\\foo\"" // No lower surrogate.
493 };
494 for (size_t i = 0; i < arraysize(cases); ++i) {
495 root.reset(JSONReader().JsonToValue(cases[i], false, false));
496 EXPECT_FALSE(root.get()) << cases[i];
497 }
initial.commit3f4a7322008-07-27 06:49:38 +0900498}
aa@chromium.org971901c2008-12-06 07:14:46 +0900499
rsesek@chromium.orga37c6162012-03-28 13:54:44 +0900500TEST(JSONReaderTest, ReadFromFile) {
501 FilePath path;
502 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path));
503 path = path.Append(FILE_PATH_LITERAL("base"))
504 .Append(FILE_PATH_LITERAL("data"))
505 .Append(FILE_PATH_LITERAL("json"));
506
507 std::string input;
508 ASSERT_TRUE(file_util::ReadFileToString(
509 path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input));
510
511 JSONReader reader;
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900512 std::string error_msg;
513 scoped_ptr<Value> root(
514 JSONReader::ReadAndReturnError(input, JSON_PARSE_RFC, NULL, &error_msg));
rsesek@chromium.orga37c6162012-03-28 13:54:44 +0900515 ASSERT_TRUE(root.get()) << reader.GetErrorMessage();
516 EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
517}
518
aa@chromium.org971901c2008-12-06 07:14:46 +0900519TEST(JSONReaderTest, ErrorMessages) {
520 // Error strings should not be modified in case of success.
521 std::string error_message;
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900522 int error_code = 0;
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900523 scoped_ptr<Value> root;
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900524 root.reset(JSONReader::ReadAndReturnError("[42]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900525 &error_code, &error_message));
aa@chromium.org09941d42008-12-24 11:07:48 +0900526 EXPECT_TRUE(error_message.empty());
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900527 EXPECT_EQ(0, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900528
529 // Test line and column counting
530 const char* big_json = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]";
531 // error here --------------------------------^
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900532 root.reset(JSONReader::ReadAndReturnError(big_json, JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900533 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900534 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900535 EXPECT_EQ(JSONReader::FormatErrorMessage(5, 9, JSONReader::kSyntaxError),
aa@chromium.org971901c2008-12-06 07:14:46 +0900536 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900537 EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900538
539 // Test each of the error conditions
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900540 root.reset(JSONReader::ReadAndReturnError("{},{}", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900541 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900542 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900543 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 3,
aa@chromium.org971901c2008-12-06 07:14:46 +0900544 JSONReader::kUnexpectedDataAfterRoot), error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900545 EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900546
547 std::string nested_json;
548 for (int i = 0; i < 101; ++i) {
549 nested_json.insert(nested_json.begin(), '[');
550 nested_json.append(1, ']');
551 }
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900552 root.reset(JSONReader::ReadAndReturnError(nested_json, JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900553 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900554 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900555 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 101, JSONReader::kTooMuchNesting),
aa@chromium.org971901c2008-12-06 07:14:46 +0900556 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900557 EXPECT_EQ(JSONReader::JSON_TOO_MUCH_NESTING, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900558
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900559 root.reset(JSONReader::ReadAndReturnError("[1,]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900560 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900561 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900562 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 4, JSONReader::kTrailingComma),
aa@chromium.org971901c2008-12-06 07:14:46 +0900563 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900564 EXPECT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900565
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900566 root.reset(JSONReader::ReadAndReturnError("{foo:\"bar\"}", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900567 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900568 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900569 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2,
aa@chromium.org971901c2008-12-06 07:14:46 +0900570 JSONReader::kUnquotedDictionaryKey), error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900571 EXPECT_EQ(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900572
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900573 root.reset(JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}",
574 JSON_PARSE_RFC,
575 &error_code,
576 &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900577 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900578 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 14, JSONReader::kTrailingComma),
aa@chromium.org971901c2008-12-06 07:14:46 +0900579 error_message);
580
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900581 root.reset(JSONReader::ReadAndReturnError("[nu]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900582 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900583 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900584 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2, JSONReader::kSyntaxError),
aa@chromium.org971901c2008-12-06 07:14:46 +0900585 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900586 EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900587
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900588 root.reset(JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900589 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900590 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900591 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
aa@chromium.org971901c2008-12-06 07:14:46 +0900592 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900593 EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900594
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900595 root.reset(JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900596 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900597 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900598 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
aa@chromium.org971901c2008-12-06 07:14:46 +0900599 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900600 EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900601
rsesek@chromium.orgdc692f52012-04-11 09:15:41 +0900602 root.reset(JSONReader::ReadAndReturnError("[\"xxx\\q\"]", JSON_PARSE_RFC,
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900603 &error_code, &error_message));
aa@chromium.orgca9c79e2008-12-30 04:59:08 +0900604 EXPECT_FALSE(root.get());
aa@chromium.org09941d42008-12-24 11:07:48 +0900605 EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
aa@chromium.org971901c2008-12-06 07:14:46 +0900606 error_message);
erikkay@chromium.org64b2cf42010-04-07 00:42:39 +0900607 EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
aa@chromium.org971901c2008-12-06 07:14:46 +0900608}
brettw@chromium.org7cd41eb2009-10-24 05:00:20 +0900609
610} // namespace base