| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/json/json_reader.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "base/json/json_parser.h" |
| #include "base/logging.h" |
| #include "base/optional.h" |
| |
| namespace base { |
| |
| // Chosen to support 99.9% of documents found in the wild late 2016. |
| // http://crbug.com/673263 |
| const int JSONReader::kStackMaxDepth = 200; |
| |
| // Values 1000 and above are used by JSONFileValueSerializer::JsonFileError. |
| static_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000, |
| "JSONReader error out of bounds"); |
| |
| const char JSONReader::kInvalidEscape[] = |
| "Invalid escape sequence."; |
| const char JSONReader::kSyntaxError[] = |
| "Syntax error."; |
| const char JSONReader::kUnexpectedToken[] = |
| "Unexpected token."; |
| const char JSONReader::kTrailingComma[] = |
| "Trailing comma not allowed."; |
| const char JSONReader::kTooMuchNesting[] = |
| "Too much nesting."; |
| const char JSONReader::kUnexpectedDataAfterRoot[] = |
| "Unexpected data after root element."; |
| const char JSONReader::kUnsupportedEncoding[] = |
| "Unsupported encoding. JSON must be UTF-8."; |
| const char JSONReader::kUnquotedDictionaryKey[] = |
| "Dictionary keys must be quoted."; |
| const char JSONReader::kInputTooLarge[] = |
| "Input string is too large (>2GB)."; |
| |
| JSONReader::ValueWithError::ValueWithError() = default; |
| |
| JSONReader::ValueWithError::ValueWithError(ValueWithError&& other) = default; |
| |
| JSONReader::ValueWithError::~ValueWithError() = default; |
| |
| JSONReader::ValueWithError& JSONReader::ValueWithError::operator=( |
| ValueWithError&& other) = default; |
| |
| JSONReader::JSONReader(int options, int max_depth) |
| : parser_(new internal::JSONParser(options, max_depth)) {} |
| |
| JSONReader::~JSONReader() = default; |
| |
| // static |
| Optional<Value> JSONReader::Read(StringPiece json, int options, int max_depth) { |
| internal::JSONParser parser(options, max_depth); |
| return parser.Parse(json); |
| } |
| |
| std::unique_ptr<Value> JSONReader::ReadDeprecated(StringPiece json, |
| int options, |
| int max_depth) { |
| Optional<Value> value = Read(json, options, max_depth); |
| return value ? Value::ToUniquePtrValue(std::move(*value)) : nullptr; |
| } |
| |
| // static |
| JSONReader::ValueWithError JSONReader::ReadAndReturnValueWithError( |
| StringPiece json, |
| int options) { |
| ValueWithError ret; |
| internal::JSONParser parser(options); |
| ret.value = parser.Parse(json); |
| if (!ret.value) { |
| ret.error_message = parser.GetErrorMessage(); |
| ret.error_code = parser.error_code(); |
| ret.error_line = parser.error_line(); |
| ret.error_column = parser.error_column(); |
| } |
| return ret; |
| } |
| |
| // static |
| std::unique_ptr<Value> JSONReader::ReadAndReturnErrorDeprecated( |
| StringPiece json, |
| int options, |
| int* error_code_out, |
| std::string* error_msg_out, |
| int* error_line_out, |
| int* error_column_out) { |
| ValueWithError ret = ReadAndReturnValueWithError(json, options); |
| if (ret.value) |
| return Value::ToUniquePtrValue(std::move(*ret.value)); |
| |
| if (error_code_out) |
| *error_code_out = ret.error_code; |
| if (error_msg_out) |
| *error_msg_out = ret.error_message; |
| if (error_line_out) |
| *error_line_out = ret.error_line; |
| if (error_column_out) |
| *error_column_out = ret.error_column; |
| return nullptr; |
| } |
| |
| // static |
| std::string JSONReader::ErrorCodeToString(JsonParseError error_code) { |
| switch (error_code) { |
| case JSON_NO_ERROR: |
| return std::string(); |
| case JSON_INVALID_ESCAPE: |
| return kInvalidEscape; |
| case JSON_SYNTAX_ERROR: |
| return kSyntaxError; |
| case JSON_UNEXPECTED_TOKEN: |
| return kUnexpectedToken; |
| case JSON_TRAILING_COMMA: |
| return kTrailingComma; |
| case JSON_TOO_MUCH_NESTING: |
| return kTooMuchNesting; |
| case JSON_UNEXPECTED_DATA_AFTER_ROOT: |
| return kUnexpectedDataAfterRoot; |
| case JSON_UNSUPPORTED_ENCODING: |
| return kUnsupportedEncoding; |
| case JSON_UNQUOTED_DICTIONARY_KEY: |
| return kUnquotedDictionaryKey; |
| case JSON_TOO_LARGE: |
| return kInputTooLarge; |
| case JSON_PARSE_ERROR_COUNT: |
| break; |
| } |
| NOTREACHED(); |
| return std::string(); |
| } |
| |
| Optional<Value> JSONReader::ReadToValue(StringPiece json) { |
| return parser_->Parse(json); |
| } |
| |
| std::unique_ptr<Value> JSONReader::ReadToValueDeprecated(StringPiece json) { |
| Optional<Value> value = parser_->Parse(json); |
| return value ? std::make_unique<Value>(std::move(*value)) : nullptr; |
| } |
| |
| JSONReader::JsonParseError JSONReader::error_code() const { |
| return parser_->error_code(); |
| } |
| |
| std::string JSONReader::GetErrorMessage() const { |
| return parser_->GetErrorMessage(); |
| } |
| |
| } // namespace base |