xref: /aosp_15_r20/external/libchrome/base/json/json_reader.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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