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