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