blob: a39b37adeb1cbd516ed9e598277ad4dc515cffd9 [file] [log] [blame]
Daniel Eratb8cf9492015-07-06 13:18:13 -06001// 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// A JSON parser. Converts strings of JSON into a Value object (see
6// base/values.h).
7// http://www.ietf.org/rfc/rfc4627.txt?number=4627
8//
9// Known limitations/deviations from the RFC:
10// - Only knows how to parse ints within the range of a signed 32 bit int and
11// decimal numbers within a double.
12// - Assumes input is encoded as UTF8. The spec says we should allow UTF-16
13// (BE or LE) and UTF-32 (BE or LE) as well.
14// - We limit nesting to 100 levels to prevent stack overflow (this is allowed
15// by the RFC).
16// - A Unicode FAQ ("http://unicode.org/faq/utf_bom.html") writes a data
17// stream may start with a Unicode Byte-Order-Mark (U+FEFF), i.e. the input
18// UTF-8 string for the JSONReader::JsonToValue() function may start with a
19// UTF-8 BOM (0xEF, 0xBB, 0xBF).
20// To avoid the function from mis-treating a UTF-8 BOM as an invalid
21// character, the function skips a Unicode BOM at the beginning of the
22// Unicode string (converted from the input UTF-8 string) before parsing it.
23//
24// TODO(tc): Add a parsing option to to relax object keys being wrapped in
25// double quotes
26// TODO(tc): Add an option to disable comment stripping
27
28#ifndef BASE_JSON_JSON_READER_H_
29#define BASE_JSON_JSON_READER_H_
30
Luis Hector Chavez94ffa552016-05-25 15:29:35 -070031#include <memory>
Daniel Eratb8cf9492015-07-06 13:18:13 -060032#include <string>
33
34#include "base/base_export.h"
Daniel Eratb8cf9492015-07-06 13:18:13 -060035#include "base/strings/string_piece.h"
36
37namespace base {
38
39class Value;
40
41namespace internal {
42class JSONParser;
43}
44
45enum JSONParserOptions {
46 // Parses the input strictly according to RFC 4627, except for where noted
47 // above.
48 JSON_PARSE_RFC = 0,
49
50 // Allows commas to exist after the last element in structures.
51 JSON_ALLOW_TRAILING_COMMAS = 1 << 0,
52
53 // The parser can perform optimizations by placing hidden data in the root of
54 // the JSON object, which speeds up certain operations on children. However,
55 // if the child is Remove()d from root, it would result in use-after-free
56 // unless it is DeepCopy()ed or this option is used.
57 JSON_DETACHABLE_CHILDREN = 1 << 1,
Jay Civelli3a83cdd2017-03-22 17:31:44 -070058
59 // If set the parser replaces invalid characters with the Unicode replacement
60 // character (U+FFFD). If not set, invalid characters trigger a hard error and
61 // parsing fails.
62 JSON_REPLACE_INVALID_CHARACTERS = 1 << 2,
Daniel Eratb8cf9492015-07-06 13:18:13 -060063};
64
65class BASE_EXPORT JSONReader {
66 public:
67 // Error codes during parsing.
68 enum JsonParseError {
69 JSON_NO_ERROR = 0,
70 JSON_INVALID_ESCAPE,
71 JSON_SYNTAX_ERROR,
72 JSON_UNEXPECTED_TOKEN,
73 JSON_TRAILING_COMMA,
74 JSON_TOO_MUCH_NESTING,
75 JSON_UNEXPECTED_DATA_AFTER_ROOT,
76 JSON_UNSUPPORTED_ENCODING,
77 JSON_UNQUOTED_DICTIONARY_KEY,
78 JSON_PARSE_ERROR_COUNT
79 };
80
81 // String versions of parse error codes.
82 static const char kInvalidEscape[];
83 static const char kSyntaxError[];
84 static const char kUnexpectedToken[];
85 static const char kTrailingComma[];
86 static const char kTooMuchNesting[];
87 static const char kUnexpectedDataAfterRoot[];
88 static const char kUnsupportedEncoding[];
89 static const char kUnquotedDictionaryKey[];
90
91 // Constructs a reader with the default options, JSON_PARSE_RFC.
92 JSONReader();
93
94 // Constructs a reader with custom options.
95 explicit JSONReader(int options);
96
97 ~JSONReader();
98
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -070099 // Reads and parses |json|, returning a Value.
100 // If |json| is not a properly formed JSON string, returns nullptr.
101 // Wrap this in base::FooValue::From() to check the Value is of type Foo and
102 // convert to a FooValue at the same time.
Luis Hector Chavez94ffa552016-05-25 15:29:35 -0700103 static std::unique_ptr<Value> Read(StringPiece json);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600104
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700105 // Same as Read() above, but the parser respects the given |options|.
Luis Hector Chavez94ffa552016-05-25 15:29:35 -0700106 static std::unique_ptr<Value> Read(StringPiece json, int options);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600107
108 // Reads and parses |json| like Read(). |error_code_out| and |error_msg_out|
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700109 // are optional. If specified and nullptr is returned, they will be populated
Daniel Eratb8cf9492015-07-06 13:18:13 -0600110 // an error code and a formatted error message (including error location if
111 // appropriate). Otherwise, they will be unmodified.
Luis Hector Chavez94ffa552016-05-25 15:29:35 -0700112 static std::unique_ptr<Value> ReadAndReturnError(
113 const StringPiece& json,
114 int options, // JSONParserOptions
115 int* error_code_out,
116 std::string* error_msg_out,
117 int* error_line_out = nullptr,
118 int* error_column_out = nullptr);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600119
120 // Converts a JSON parse error code into a human readable message.
121 // Returns an empty string if error_code is JSON_NO_ERROR.
122 static std::string ErrorCodeToString(JsonParseError error_code);
123
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700124 // Non-static version of Read() above.
Luis Hector Chavez94ffa552016-05-25 15:29:35 -0700125 std::unique_ptr<Value> ReadToValue(StringPiece json);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600126
127 // Returns the error code if the last call to ReadToValue() failed.
128 // Returns JSON_NO_ERROR otherwise.
129 JsonParseError error_code() const;
130
131 // Converts error_code_ to a human-readable string, including line and column
132 // numbers if appropriate.
133 std::string GetErrorMessage() const;
134
135 private:
Luis Hector Chavez94ffa552016-05-25 15:29:35 -0700136 std::unique_ptr<internal::JSONParser> parser_;
Daniel Eratb8cf9492015-07-06 13:18:13 -0600137};
138
139} // namespace base
140
141#endif // BASE_JSON_JSON_READER_H_