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_reader.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <utility>
8*635a8641SAndroid Build Coastguard Worker #include <vector>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include "base/json/json_parser.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/optional.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker namespace base {
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker // Chosen to support 99.9% of documents found in the wild late 2016.
18*635a8641SAndroid Build Coastguard Worker // http://crbug.com/673263
19*635a8641SAndroid Build Coastguard Worker const int JSONReader::kStackMaxDepth = 200;
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker // Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
22*635a8641SAndroid Build Coastguard Worker static_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
23*635a8641SAndroid Build Coastguard Worker "JSONReader error out of bounds");
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker const char JSONReader::kInvalidEscape[] =
26*635a8641SAndroid Build Coastguard Worker "Invalid escape sequence.";
27*635a8641SAndroid Build Coastguard Worker const char JSONReader::kSyntaxError[] =
28*635a8641SAndroid Build Coastguard Worker "Syntax error.";
29*635a8641SAndroid Build Coastguard Worker const char JSONReader::kUnexpectedToken[] =
30*635a8641SAndroid Build Coastguard Worker "Unexpected token.";
31*635a8641SAndroid Build Coastguard Worker const char JSONReader::kTrailingComma[] =
32*635a8641SAndroid Build Coastguard Worker "Trailing comma not allowed.";
33*635a8641SAndroid Build Coastguard Worker const char JSONReader::kTooMuchNesting[] =
34*635a8641SAndroid Build Coastguard Worker "Too much nesting.";
35*635a8641SAndroid Build Coastguard Worker const char JSONReader::kUnexpectedDataAfterRoot[] =
36*635a8641SAndroid Build Coastguard Worker "Unexpected data after root element.";
37*635a8641SAndroid Build Coastguard Worker const char JSONReader::kUnsupportedEncoding[] =
38*635a8641SAndroid Build Coastguard Worker "Unsupported encoding. JSON must be UTF-8.";
39*635a8641SAndroid Build Coastguard Worker const char JSONReader::kUnquotedDictionaryKey[] =
40*635a8641SAndroid Build Coastguard Worker "Dictionary keys must be quoted.";
41*635a8641SAndroid Build Coastguard Worker const char JSONReader::kInputTooLarge[] =
42*635a8641SAndroid Build Coastguard Worker "Input string is too large (>2GB).";
43*635a8641SAndroid Build Coastguard Worker
JSONReader(int options,int max_depth)44*635a8641SAndroid Build Coastguard Worker JSONReader::JSONReader(int options, int max_depth)
45*635a8641SAndroid Build Coastguard Worker : parser_(new internal::JSONParser(options, max_depth)) {}
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker JSONReader::~JSONReader() = default;
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker // static
Read(StringPiece json,int options,int max_depth)50*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> JSONReader::Read(StringPiece json,
51*635a8641SAndroid Build Coastguard Worker int options,
52*635a8641SAndroid Build Coastguard Worker int max_depth) {
53*635a8641SAndroid Build Coastguard Worker internal::JSONParser parser(options, max_depth);
54*635a8641SAndroid Build Coastguard Worker Optional<Value> root = parser.Parse(json);
55*635a8641SAndroid Build Coastguard Worker return root ? std::make_unique<Value>(std::move(*root)) : nullptr;
56*635a8641SAndroid Build Coastguard Worker }
57*635a8641SAndroid Build Coastguard Worker
58*635a8641SAndroid Build Coastguard Worker
59*635a8641SAndroid Build Coastguard Worker // static
ReadAndReturnError(StringPiece json,int options,int * error_code_out,std::string * error_msg_out,int * error_line_out,int * error_column_out)60*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> JSONReader::ReadAndReturnError(
61*635a8641SAndroid Build Coastguard Worker StringPiece json,
62*635a8641SAndroid Build Coastguard Worker int options,
63*635a8641SAndroid Build Coastguard Worker int* error_code_out,
64*635a8641SAndroid Build Coastguard Worker std::string* error_msg_out,
65*635a8641SAndroid Build Coastguard Worker int* error_line_out,
66*635a8641SAndroid Build Coastguard Worker int* error_column_out) {
67*635a8641SAndroid Build Coastguard Worker internal::JSONParser parser(options);
68*635a8641SAndroid Build Coastguard Worker Optional<Value> root = parser.Parse(json);
69*635a8641SAndroid Build Coastguard Worker if (!root) {
70*635a8641SAndroid Build Coastguard Worker if (error_code_out)
71*635a8641SAndroid Build Coastguard Worker *error_code_out = parser.error_code();
72*635a8641SAndroid Build Coastguard Worker if (error_msg_out)
73*635a8641SAndroid Build Coastguard Worker *error_msg_out = parser.GetErrorMessage();
74*635a8641SAndroid Build Coastguard Worker if (error_line_out)
75*635a8641SAndroid Build Coastguard Worker *error_line_out = parser.error_line();
76*635a8641SAndroid Build Coastguard Worker if (error_column_out)
77*635a8641SAndroid Build Coastguard Worker *error_column_out = parser.error_column();
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker return root ? std::make_unique<Value>(std::move(*root)) : nullptr;
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker
83*635a8641SAndroid Build Coastguard Worker // static
ErrorCodeToString(JsonParseError error_code)84*635a8641SAndroid Build Coastguard Worker std::string JSONReader::ErrorCodeToString(JsonParseError error_code) {
85*635a8641SAndroid Build Coastguard Worker switch (error_code) {
86*635a8641SAndroid Build Coastguard Worker case JSON_NO_ERROR:
87*635a8641SAndroid Build Coastguard Worker return std::string();
88*635a8641SAndroid Build Coastguard Worker case JSON_INVALID_ESCAPE:
89*635a8641SAndroid Build Coastguard Worker return kInvalidEscape;
90*635a8641SAndroid Build Coastguard Worker case JSON_SYNTAX_ERROR:
91*635a8641SAndroid Build Coastguard Worker return kSyntaxError;
92*635a8641SAndroid Build Coastguard Worker case JSON_UNEXPECTED_TOKEN:
93*635a8641SAndroid Build Coastguard Worker return kUnexpectedToken;
94*635a8641SAndroid Build Coastguard Worker case JSON_TRAILING_COMMA:
95*635a8641SAndroid Build Coastguard Worker return kTrailingComma;
96*635a8641SAndroid Build Coastguard Worker case JSON_TOO_MUCH_NESTING:
97*635a8641SAndroid Build Coastguard Worker return kTooMuchNesting;
98*635a8641SAndroid Build Coastguard Worker case JSON_UNEXPECTED_DATA_AFTER_ROOT:
99*635a8641SAndroid Build Coastguard Worker return kUnexpectedDataAfterRoot;
100*635a8641SAndroid Build Coastguard Worker case JSON_UNSUPPORTED_ENCODING:
101*635a8641SAndroid Build Coastguard Worker return kUnsupportedEncoding;
102*635a8641SAndroid Build Coastguard Worker case JSON_UNQUOTED_DICTIONARY_KEY:
103*635a8641SAndroid Build Coastguard Worker return kUnquotedDictionaryKey;
104*635a8641SAndroid Build Coastguard Worker case JSON_TOO_LARGE:
105*635a8641SAndroid Build Coastguard Worker return kInputTooLarge;
106*635a8641SAndroid Build Coastguard Worker case JSON_PARSE_ERROR_COUNT:
107*635a8641SAndroid Build Coastguard Worker break;
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker NOTREACHED();
110*635a8641SAndroid Build Coastguard Worker return std::string();
111*635a8641SAndroid Build Coastguard Worker }
112*635a8641SAndroid Build Coastguard Worker
ReadToValue(StringPiece json)113*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> JSONReader::ReadToValue(StringPiece json) {
114*635a8641SAndroid Build Coastguard Worker Optional<Value> value = parser_->Parse(json);
115*635a8641SAndroid Build Coastguard Worker return value ? std::make_unique<Value>(std::move(*value)) : nullptr;
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker
error_code() const118*635a8641SAndroid Build Coastguard Worker JSONReader::JsonParseError JSONReader::error_code() const {
119*635a8641SAndroid Build Coastguard Worker return parser_->error_code();
120*635a8641SAndroid Build Coastguard Worker }
121*635a8641SAndroid Build Coastguard Worker
GetErrorMessage() const122*635a8641SAndroid Build Coastguard Worker std::string JSONReader::GetErrorMessage() const {
123*635a8641SAndroid Build Coastguard Worker return parser_->GetErrorMessage();
124*635a8641SAndroid Build Coastguard Worker }
125*635a8641SAndroid Build Coastguard Worker
126*635a8641SAndroid Build Coastguard Worker } // namespace base
127