1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/json/json_parser.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/optional.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
16*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Worker namespace base {
19*635a8641SAndroid Build Coastguard Worker namespace internal {
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker class JSONParserTest : public testing::Test {
22*635a8641SAndroid Build Coastguard Worker public:
NewTestParser(const std::string & input,int options=JSON_PARSE_RFC)23*635a8641SAndroid Build Coastguard Worker JSONParser* NewTestParser(const std::string& input,
24*635a8641SAndroid Build Coastguard Worker int options = JSON_PARSE_RFC) {
25*635a8641SAndroid Build Coastguard Worker JSONParser* parser = new JSONParser(options);
26*635a8641SAndroid Build Coastguard Worker parser->input_ = input;
27*635a8641SAndroid Build Coastguard Worker parser->index_ = 0;
28*635a8641SAndroid Build Coastguard Worker return parser;
29*635a8641SAndroid Build Coastguard Worker }
30*635a8641SAndroid Build Coastguard Worker
31*635a8641SAndroid Build Coastguard Worker // MSan will do a better job detecting over-read errors if the input is
32*635a8641SAndroid Build Coastguard Worker // not nul-terminated on the heap. This will copy |input| to a new buffer
33*635a8641SAndroid Build Coastguard Worker // owned by |owner|, returning a StringPiece to |owner|.
MakeNotNullTerminatedInput(const char * input,std::unique_ptr<char[]> * owner)34*635a8641SAndroid Build Coastguard Worker StringPiece MakeNotNullTerminatedInput(const char* input,
35*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]>* owner) {
36*635a8641SAndroid Build Coastguard Worker size_t str_len = strlen(input);
37*635a8641SAndroid Build Coastguard Worker owner->reset(new char[str_len]);
38*635a8641SAndroid Build Coastguard Worker memcpy(owner->get(), input, str_len);
39*635a8641SAndroid Build Coastguard Worker return StringPiece(owner->get(), str_len);
40*635a8641SAndroid Build Coastguard Worker }
41*635a8641SAndroid Build Coastguard Worker
TestLastThree(JSONParser * parser)42*635a8641SAndroid Build Coastguard Worker void TestLastThree(JSONParser* parser) {
43*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->PeekChar());
44*635a8641SAndroid Build Coastguard Worker parser->ConsumeChar();
45*635a8641SAndroid Build Coastguard Worker EXPECT_EQ('|', *parser->PeekChar());
46*635a8641SAndroid Build Coastguard Worker parser->ConsumeChar();
47*635a8641SAndroid Build Coastguard Worker EXPECT_EQ('\0', *parser->pos());
48*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(parser->index_), parser->input_.length());
49*635a8641SAndroid Build Coastguard Worker }
50*635a8641SAndroid Build Coastguard Worker };
51*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,NextChar)52*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, NextChar) {
53*635a8641SAndroid Build Coastguard Worker std::string input("Hello world");
54*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker EXPECT_EQ('H', *parser->pos());
57*635a8641SAndroid Build Coastguard Worker for (size_t i = 1; i < input.length(); ++i) {
58*635a8641SAndroid Build Coastguard Worker parser->ConsumeChar();
59*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(input[i], *parser->PeekChar());
60*635a8641SAndroid Build Coastguard Worker }
61*635a8641SAndroid Build Coastguard Worker parser->ConsumeChar();
62*635a8641SAndroid Build Coastguard Worker EXPECT_EQ('\0', *parser->pos());
63*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(parser->index_), parser->input_.length());
64*635a8641SAndroid Build Coastguard Worker }
65*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ConsumeString)66*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ConsumeString) {
67*635a8641SAndroid Build Coastguard Worker std::string input("\"test\",|");
68*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
69*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeString());
70*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
71*635a8641SAndroid Build Coastguard Worker
72*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
73*635a8641SAndroid Build Coastguard Worker
74*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
75*635a8641SAndroid Build Coastguard Worker std::string str;
76*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsString(&str));
77*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("test", str);
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ConsumeList)80*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ConsumeList) {
81*635a8641SAndroid Build Coastguard Worker std::string input("[true, false],|");
82*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
83*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeList());
84*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
85*635a8641SAndroid Build Coastguard Worker
86*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
89*635a8641SAndroid Build Coastguard Worker base::ListValue* list;
90*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsList(&list));
91*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2u, list->GetSize());
92*635a8641SAndroid Build Coastguard Worker }
93*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ConsumeDictionary)94*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ConsumeDictionary) {
95*635a8641SAndroid Build Coastguard Worker std::string input("{\"abc\":\"def\"},|");
96*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
97*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeDictionary());
98*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
99*635a8641SAndroid Build Coastguard Worker
100*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
101*635a8641SAndroid Build Coastguard Worker
102*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
103*635a8641SAndroid Build Coastguard Worker base::DictionaryValue* dict;
104*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsDictionary(&dict));
105*635a8641SAndroid Build Coastguard Worker std::string str;
106*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(dict->GetString("abc", &str));
107*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("def", str);
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ConsumeLiterals)110*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ConsumeLiterals) {
111*635a8641SAndroid Build Coastguard Worker // Literal |true|.
112*635a8641SAndroid Build Coastguard Worker std::string input("true,|");
113*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
114*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeLiteral());
115*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
116*635a8641SAndroid Build Coastguard Worker
117*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
118*635a8641SAndroid Build Coastguard Worker
119*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
120*635a8641SAndroid Build Coastguard Worker bool bool_value = false;
121*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsBoolean(&bool_value));
122*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(bool_value);
123*635a8641SAndroid Build Coastguard Worker
124*635a8641SAndroid Build Coastguard Worker // Literal |false|.
125*635a8641SAndroid Build Coastguard Worker input = "false,|";
126*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
127*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeLiteral();
128*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
129*635a8641SAndroid Build Coastguard Worker
130*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
133*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsBoolean(&bool_value));
134*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(bool_value);
135*635a8641SAndroid Build Coastguard Worker
136*635a8641SAndroid Build Coastguard Worker // Literal |null|.
137*635a8641SAndroid Build Coastguard Worker input = "null,|";
138*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
139*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeLiteral();
140*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
141*635a8641SAndroid Build Coastguard Worker
142*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
143*635a8641SAndroid Build Coastguard Worker
144*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
145*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->is_none());
146*635a8641SAndroid Build Coastguard Worker }
147*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ConsumeNumbers)148*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ConsumeNumbers) {
149*635a8641SAndroid Build Coastguard Worker // Integer.
150*635a8641SAndroid Build Coastguard Worker std::string input("1234,|");
151*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(NewTestParser(input));
152*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeNumber());
153*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
154*635a8641SAndroid Build Coastguard Worker
155*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
156*635a8641SAndroid Build Coastguard Worker
157*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
158*635a8641SAndroid Build Coastguard Worker int number_i;
159*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsInteger(&number_i));
160*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1234, number_i);
161*635a8641SAndroid Build Coastguard Worker
162*635a8641SAndroid Build Coastguard Worker // Negative integer.
163*635a8641SAndroid Build Coastguard Worker input = "-1234,|";
164*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
165*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeNumber();
166*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
167*635a8641SAndroid Build Coastguard Worker
168*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
169*635a8641SAndroid Build Coastguard Worker
170*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
171*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsInteger(&number_i));
172*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(-1234, number_i);
173*635a8641SAndroid Build Coastguard Worker
174*635a8641SAndroid Build Coastguard Worker // Double.
175*635a8641SAndroid Build Coastguard Worker input = "12.34,|";
176*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
177*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeNumber();
178*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
179*635a8641SAndroid Build Coastguard Worker
180*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
181*635a8641SAndroid Build Coastguard Worker
182*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
183*635a8641SAndroid Build Coastguard Worker double number_d;
184*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsDouble(&number_d));
185*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(12.34, number_d);
186*635a8641SAndroid Build Coastguard Worker
187*635a8641SAndroid Build Coastguard Worker // Scientific.
188*635a8641SAndroid Build Coastguard Worker input = "42e3,|";
189*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
190*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeNumber();
191*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
194*635a8641SAndroid Build Coastguard Worker
195*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
196*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsDouble(&number_d));
197*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(42000, number_d);
198*635a8641SAndroid Build Coastguard Worker
199*635a8641SAndroid Build Coastguard Worker // Negative scientific.
200*635a8641SAndroid Build Coastguard Worker input = "314159e-5,|";
201*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
202*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeNumber();
203*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
204*635a8641SAndroid Build Coastguard Worker
205*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
206*635a8641SAndroid Build Coastguard Worker
207*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
208*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsDouble(&number_d));
209*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(3.14159, number_d);
210*635a8641SAndroid Build Coastguard Worker
211*635a8641SAndroid Build Coastguard Worker // Positive scientific.
212*635a8641SAndroid Build Coastguard Worker input = "0.42e+3,|";
213*635a8641SAndroid Build Coastguard Worker parser.reset(NewTestParser(input));
214*635a8641SAndroid Build Coastguard Worker value = parser->ConsumeNumber();
215*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(',', *parser->pos());
216*635a8641SAndroid Build Coastguard Worker
217*635a8641SAndroid Build Coastguard Worker TestLastThree(parser.get());
218*635a8641SAndroid Build Coastguard Worker
219*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
220*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsDouble(&number_d));
221*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(420, number_d);
222*635a8641SAndroid Build Coastguard Worker }
223*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ErrorMessages)224*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ErrorMessages) {
225*635a8641SAndroid Build Coastguard Worker // Error strings should not be modified in case of success.
226*635a8641SAndroid Build Coastguard Worker std::string error_message;
227*635a8641SAndroid Build Coastguard Worker int error_code = 0;
228*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> root = JSONReader::ReadAndReturnError(
229*635a8641SAndroid Build Coastguard Worker "[42]", JSON_PARSE_RFC, &error_code, &error_message);
230*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(error_message.empty());
231*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, error_code);
232*635a8641SAndroid Build Coastguard Worker
233*635a8641SAndroid Build Coastguard Worker // Test line and column counting
234*635a8641SAndroid Build Coastguard Worker const char big_json[] = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]";
235*635a8641SAndroid Build Coastguard Worker // error here ----------------------------------^
236*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError(big_json, JSON_PARSE_RFC, &error_code,
237*635a8641SAndroid Build Coastguard Worker &error_message);
238*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
239*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(5, 10, JSONReader::kSyntaxError),
240*635a8641SAndroid Build Coastguard Worker error_message);
241*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
242*635a8641SAndroid Build Coastguard Worker
243*635a8641SAndroid Build Coastguard Worker error_code = 0;
244*635a8641SAndroid Build Coastguard Worker error_message = "";
245*635a8641SAndroid Build Coastguard Worker // Test line and column counting with "\r\n" line ending
246*635a8641SAndroid Build Coastguard Worker const char big_json_crlf[] =
247*635a8641SAndroid Build Coastguard Worker "[\r\n0,\r\n1,\r\n2,\r\n3,4,5,6 7,\r\n8,\r\n9\r\n]";
248*635a8641SAndroid Build Coastguard Worker // error here ----------------------^
249*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError(big_json_crlf, JSON_PARSE_RFC,
250*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
251*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
252*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(5, 10, JSONReader::kSyntaxError),
253*635a8641SAndroid Build Coastguard Worker error_message);
254*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
255*635a8641SAndroid Build Coastguard Worker
256*635a8641SAndroid Build Coastguard Worker // Test each of the error conditions
257*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("{},{}", JSON_PARSE_RFC, &error_code,
258*635a8641SAndroid Build Coastguard Worker &error_message);
259*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
260*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 3,
261*635a8641SAndroid Build Coastguard Worker JSONReader::kUnexpectedDataAfterRoot), error_message);
262*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, error_code);
263*635a8641SAndroid Build Coastguard Worker
264*635a8641SAndroid Build Coastguard Worker std::string nested_json;
265*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < 201; ++i) {
266*635a8641SAndroid Build Coastguard Worker nested_json.insert(nested_json.begin(), '[');
267*635a8641SAndroid Build Coastguard Worker nested_json.append(1, ']');
268*635a8641SAndroid Build Coastguard Worker }
269*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError(nested_json, JSON_PARSE_RFC,
270*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
271*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
272*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 200, JSONReader::kTooMuchNesting),
273*635a8641SAndroid Build Coastguard Worker error_message);
274*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_TOO_MUCH_NESTING, error_code);
275*635a8641SAndroid Build Coastguard Worker
276*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("[1,]", JSON_PARSE_RFC, &error_code,
277*635a8641SAndroid Build Coastguard Worker &error_message);
278*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
279*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 4, JSONReader::kTrailingComma),
280*635a8641SAndroid Build Coastguard Worker error_message);
281*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code);
282*635a8641SAndroid Build Coastguard Worker
283*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("{foo:\"bar\"}", JSON_PARSE_RFC,
284*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
285*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
286*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2,
287*635a8641SAndroid Build Coastguard Worker JSONReader::kUnquotedDictionaryKey), error_message);
288*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, error_code);
289*635a8641SAndroid Build Coastguard Worker
290*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}", JSON_PARSE_RFC,
291*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
292*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
293*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 14, JSONReader::kTrailingComma),
294*635a8641SAndroid Build Coastguard Worker error_message);
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("[nu]", JSON_PARSE_RFC, &error_code,
297*635a8641SAndroid Build Coastguard Worker &error_message);
298*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
299*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2, JSONReader::kSyntaxError),
300*635a8641SAndroid Build Coastguard Worker error_message);
301*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
302*635a8641SAndroid Build Coastguard Worker
303*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", JSON_PARSE_RFC,
304*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
305*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
306*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
307*635a8641SAndroid Build Coastguard Worker error_message);
308*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
309*635a8641SAndroid Build Coastguard Worker
310*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", JSON_PARSE_RFC,
311*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
312*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
313*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
314*635a8641SAndroid Build Coastguard Worker error_message);
315*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
316*635a8641SAndroid Build Coastguard Worker
317*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError("[\"xxx\\q\"]", JSON_PARSE_RFC,
318*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
319*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(root.get());
320*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
321*635a8641SAndroid Build Coastguard Worker error_message);
322*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
323*635a8641SAndroid Build Coastguard Worker
324*635a8641SAndroid Build Coastguard Worker root = JSONReader::ReadAndReturnError(("[\"\\ufffe\"]"), JSON_PARSE_RFC,
325*635a8641SAndroid Build Coastguard Worker &error_code, &error_message);
326*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONParser::FormatErrorMessage(1, 8, JSONReader::kInvalidEscape),
327*635a8641SAndroid Build Coastguard Worker error_message);
328*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
329*635a8641SAndroid Build Coastguard Worker }
330*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,Decode4ByteUtf8Char)331*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, Decode4ByteUtf8Char) {
332*635a8641SAndroid Build Coastguard Worker // This test strings contains a 4 byte unicode character (a smiley!) that the
333*635a8641SAndroid Build Coastguard Worker // reader should be able to handle (the character is \xf0\x9f\x98\x87).
334*635a8641SAndroid Build Coastguard Worker const char kUtf8Data[] =
335*635a8641SAndroid Build Coastguard Worker "[\"\",[],[],[],{\"google:suggesttype\":[]}]";
336*635a8641SAndroid Build Coastguard Worker std::string error_message;
337*635a8641SAndroid Build Coastguard Worker int error_code = 0;
338*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> root = JSONReader::ReadAndReturnError(
339*635a8641SAndroid Build Coastguard Worker kUtf8Data, JSON_PARSE_RFC, &error_code, &error_message);
340*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(root.get()) << error_message;
341*635a8641SAndroid Build Coastguard Worker }
342*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,DecodeUnicodeNonCharacter)343*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, DecodeUnicodeNonCharacter) {
344*635a8641SAndroid Build Coastguard Worker // Tests Unicode code points (encoded as escaped UTF-16) that are not valid
345*635a8641SAndroid Build Coastguard Worker // characters.
346*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read("[\"\\ufdd0\"]"));
347*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read("[\"\\ufffe\"]"));
348*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read("[\"\\ud83f\\udffe\"]"));
349*635a8641SAndroid Build Coastguard Worker
350*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(
351*635a8641SAndroid Build Coastguard Worker JSONReader::Read("[\"\\ufdd0\"]", JSON_REPLACE_INVALID_CHARACTERS));
352*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(
353*635a8641SAndroid Build Coastguard Worker JSONReader::Read("[\"\\ufffe\"]", JSON_REPLACE_INVALID_CHARACTERS));
354*635a8641SAndroid Build Coastguard Worker }
355*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,DecodeNegativeEscapeSequence)356*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, DecodeNegativeEscapeSequence) {
357*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read("[\"\\x-A\"]"));
358*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read("[\"\\u-00A\"]"));
359*635a8641SAndroid Build Coastguard Worker }
360*635a8641SAndroid Build Coastguard Worker
361*635a8641SAndroid Build Coastguard Worker // Verifies invalid utf-8 characters are replaced.
TEST_F(JSONParserTest,ReplaceInvalidCharacters)362*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ReplaceInvalidCharacters) {
363*635a8641SAndroid Build Coastguard Worker const std::string bogus_char = "";
364*635a8641SAndroid Build Coastguard Worker const std::string quoted_bogus_char = "\"" + bogus_char + "\"";
365*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(
366*635a8641SAndroid Build Coastguard Worker NewTestParser(quoted_bogus_char, JSON_REPLACE_INVALID_CHARACTERS));
367*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeString());
368*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
369*635a8641SAndroid Build Coastguard Worker std::string str;
370*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsString(&str));
371*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kUnicodeReplacementString, str);
372*635a8641SAndroid Build Coastguard Worker }
373*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ReplaceInvalidUTF16EscapeSequence)374*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ReplaceInvalidUTF16EscapeSequence) {
375*635a8641SAndroid Build Coastguard Worker const std::string invalid = "\"\\ufffe\"";
376*635a8641SAndroid Build Coastguard Worker std::unique_ptr<JSONParser> parser(
377*635a8641SAndroid Build Coastguard Worker NewTestParser(invalid, JSON_REPLACE_INVALID_CHARACTERS));
378*635a8641SAndroid Build Coastguard Worker Optional<Value> value(parser->ConsumeString());
379*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(value);
380*635a8641SAndroid Build Coastguard Worker std::string str;
381*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value->GetAsString(&str));
382*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kUnicodeReplacementString, str);
383*635a8641SAndroid Build Coastguard Worker }
384*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,ParseNumberErrors)385*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, ParseNumberErrors) {
386*635a8641SAndroid Build Coastguard Worker const struct {
387*635a8641SAndroid Build Coastguard Worker const char* input;
388*635a8641SAndroid Build Coastguard Worker bool parse_success;
389*635a8641SAndroid Build Coastguard Worker double value;
390*635a8641SAndroid Build Coastguard Worker } kCases[] = {
391*635a8641SAndroid Build Coastguard Worker // clang-format off
392*635a8641SAndroid Build Coastguard Worker {"1", true, 1},
393*635a8641SAndroid Build Coastguard Worker {"2.", false, 0},
394*635a8641SAndroid Build Coastguard Worker {"42", true, 42},
395*635a8641SAndroid Build Coastguard Worker {"6e", false, 0},
396*635a8641SAndroid Build Coastguard Worker {"43e2", true, 4300},
397*635a8641SAndroid Build Coastguard Worker {"43e-", false, 0},
398*635a8641SAndroid Build Coastguard Worker {"9e-3", true, 0.009},
399*635a8641SAndroid Build Coastguard Worker {"2e+", false, 0},
400*635a8641SAndroid Build Coastguard Worker {"2e+2", true, 200},
401*635a8641SAndroid Build Coastguard Worker // clang-format on
402*635a8641SAndroid Build Coastguard Worker };
403*635a8641SAndroid Build Coastguard Worker
404*635a8641SAndroid Build Coastguard Worker for (unsigned int i = 0; i < arraysize(kCases); ++i) {
405*635a8641SAndroid Build Coastguard Worker auto test_case = kCases[i];
406*635a8641SAndroid Build Coastguard Worker SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case.input));
407*635a8641SAndroid Build Coastguard Worker
408*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> input_owner;
409*635a8641SAndroid Build Coastguard Worker StringPiece input =
410*635a8641SAndroid Build Coastguard Worker MakeNotNullTerminatedInput(test_case.input, &input_owner);
411*635a8641SAndroid Build Coastguard Worker
412*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> result = JSONReader::Read(input);
413*635a8641SAndroid Build Coastguard Worker if (test_case.parse_success) {
414*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(result);
415*635a8641SAndroid Build Coastguard Worker } else {
416*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(result);
417*635a8641SAndroid Build Coastguard Worker }
418*635a8641SAndroid Build Coastguard Worker
419*635a8641SAndroid Build Coastguard Worker if (!result)
420*635a8641SAndroid Build Coastguard Worker continue;
421*635a8641SAndroid Build Coastguard Worker
422*635a8641SAndroid Build Coastguard Worker double double_value = 0;
423*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(result->GetAsDouble(&double_value));
424*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(test_case.value, double_value);
425*635a8641SAndroid Build Coastguard Worker }
426*635a8641SAndroid Build Coastguard Worker }
427*635a8641SAndroid Build Coastguard Worker
TEST_F(JSONParserTest,UnterminatedInputs)428*635a8641SAndroid Build Coastguard Worker TEST_F(JSONParserTest, UnterminatedInputs) {
429*635a8641SAndroid Build Coastguard Worker const char* kCases[] = {
430*635a8641SAndroid Build Coastguard Worker // clang-format off
431*635a8641SAndroid Build Coastguard Worker "/",
432*635a8641SAndroid Build Coastguard Worker "//",
433*635a8641SAndroid Build Coastguard Worker "/*",
434*635a8641SAndroid Build Coastguard Worker "\"xxxxxx",
435*635a8641SAndroid Build Coastguard Worker "\"",
436*635a8641SAndroid Build Coastguard Worker "{ ",
437*635a8641SAndroid Build Coastguard Worker "[\t",
438*635a8641SAndroid Build Coastguard Worker "tru",
439*635a8641SAndroid Build Coastguard Worker "fals",
440*635a8641SAndroid Build Coastguard Worker "nul",
441*635a8641SAndroid Build Coastguard Worker "\"\\x",
442*635a8641SAndroid Build Coastguard Worker "\"\\x2",
443*635a8641SAndroid Build Coastguard Worker "\"\\u123",
444*635a8641SAndroid Build Coastguard Worker "\"\\uD803\\u",
445*635a8641SAndroid Build Coastguard Worker "\"\\",
446*635a8641SAndroid Build Coastguard Worker "\"\\/",
447*635a8641SAndroid Build Coastguard Worker // clang-format on
448*635a8641SAndroid Build Coastguard Worker };
449*635a8641SAndroid Build Coastguard Worker
450*635a8641SAndroid Build Coastguard Worker for (unsigned int i = 0; i < arraysize(kCases); ++i) {
451*635a8641SAndroid Build Coastguard Worker auto* test_case = kCases[i];
452*635a8641SAndroid Build Coastguard Worker SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case));
453*635a8641SAndroid Build Coastguard Worker
454*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> input_owner;
455*635a8641SAndroid Build Coastguard Worker StringPiece input = MakeNotNullTerminatedInput(test_case, &input_owner);
456*635a8641SAndroid Build Coastguard Worker
457*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONReader::Read(input));
458*635a8641SAndroid Build Coastguard Worker }
459*635a8641SAndroid Build Coastguard Worker }
460*635a8641SAndroid Build Coastguard Worker
461*635a8641SAndroid Build Coastguard Worker } // namespace internal
462*635a8641SAndroid Build Coastguard Worker } // namespace base
463