diff options
author | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-06 15:42:39 +0000 |
---|---|---|
committer | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-06 15:42:39 +0000 |
commit | ba3996771f6d19298ee655992b2f6291a314ea76 (patch) | |
tree | e5d88f89e7e98aa6ee60af431dc5dfa426d727b2 /base/json/json_reader.cc | |
parent | 44a91f51ec8dd8d1373e28ef6f3f0ab410db942f (diff) | |
download | chromium_src-ba3996771f6d19298ee655992b2f6291a314ea76.zip chromium_src-ba3996771f6d19298ee655992b2f6291a314ea76.tar.gz chromium_src-ba3996771f6d19298ee655992b2f6291a314ea76.tar.bz2 |
detect preferences errors
BUG=38352
TEST=none
Review URL: http://codereview.chromium.org/1120006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43715 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/json/json_reader.cc')
-rw-r--r-- | base/json/json_reader.cc | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/base/json/json_reader.cc b/base/json/json_reader.cc index bdc682b..cf9ce02 100644 --- a/base/json/json_reader.cc +++ b/base/json/json_reader.cc @@ -95,40 +95,79 @@ const char* JSONReader::kUnquotedDictionaryKey = /* static */ Value* JSONReader::Read(const std::string& json, bool allow_trailing_comma) { - return ReadAndReturnError(json, allow_trailing_comma, NULL); + return ReadAndReturnError(json, allow_trailing_comma, NULL, NULL); } /* static */ Value* JSONReader::ReadAndReturnError(const std::string& json, bool allow_trailing_comma, - std::string *error_message_out) { + int* error_code_out, + std::string* error_msg_out) { JSONReader reader = JSONReader(); Value* root = reader.JsonToValue(json, true, allow_trailing_comma); if (root) return root; - if (error_message_out) - *error_message_out = reader.error_message(); + if (error_code_out) + *error_code_out = reader.error_code(); + if (error_msg_out) + *error_msg_out = reader.GetErrorMessage(); return NULL; } /* static */ std::string JSONReader::FormatErrorMessage(int line, int column, - const char* description) { - return StringPrintf("Line: %i, column: %i, %s", - line, column, description); + const std::string& description) { + if (line || column) { + return StringPrintf("Line: %i, column: %i, %s", + line, column, description.c_str()); + } + return description; +} + +/* static */ +std::string JSONReader::ErrorCodeToString(JsonParseError error_code) { + switch (error_code) { + case JSON_NO_ERROR: + return std::string(); + case JSON_BAD_ROOT_ELEMENT_TYPE: + return kBadRootElementType; + case JSON_INVALID_ESCAPE: + return kInvalidEscape; + case JSON_SYNTAX_ERROR: + return kSyntaxError; + 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; + default: + NOTREACHED(); + return std::string(); + } +} + +std::string JSONReader::GetErrorMessage() const { + return FormatErrorMessage(error_line_, error_col_, + ErrorCodeToString(error_code_)); } JSONReader::JSONReader() : start_pos_(NULL), json_pos_(NULL), stack_depth_(0), - allow_trailing_comma_(false) {} + allow_trailing_comma_(false), + error_code_(JSON_NO_ERROR), error_line_(0), error_col_(0) {} Value* JSONReader::JsonToValue(const std::string& json, bool check_root, bool allow_trailing_comma) { // The input must be in UTF-8. if (!IsStringUTF8(json.c_str())) { - error_message_ = kUnsupportedEncoding; + error_code_ = JSON_UNSUPPORTED_ENCODING; return NULL; } @@ -149,20 +188,20 @@ Value* JSONReader::JsonToValue(const std::string& json, bool check_root, json_pos_ = start_pos_; allow_trailing_comma_ = allow_trailing_comma; stack_depth_ = 0; - error_message_.clear(); + error_code_ = JSON_NO_ERROR; scoped_ptr<Value> root(BuildValue(check_root)); if (root.get()) { if (ParseToken().type == Token::END_OF_INPUT) { return root.release(); } else { - SetErrorMessage(kUnexpectedDataAfterRoot, json_pos_); + SetErrorCode(JSON_UNEXPECTED_DATA_AFTER_ROOT, json_pos_); } } // Default to calling errors "syntax errors". - if (error_message_.empty()) - SetErrorMessage(kSyntaxError, json_pos_); + if (error_code_ == 0) + SetErrorCode(JSON_SYNTAX_ERROR, json_pos_); return NULL; } @@ -170,7 +209,7 @@ Value* JSONReader::JsonToValue(const std::string& json, bool check_root, Value* JSONReader::BuildValue(bool is_root) { ++stack_depth_; if (stack_depth_ > kStackLimit) { - SetErrorMessage(kTooMuchNesting, json_pos_); + SetErrorCode(JSON_TOO_MUCH_NESTING, json_pos_); return NULL; } @@ -178,7 +217,7 @@ Value* JSONReader::BuildValue(bool is_root) { // The root token must be an array or an object. if (is_root && token.type != Token::OBJECT_BEGIN && token.type != Token::ARRAY_BEGIN) { - SetErrorMessage(kBadRootElementType, json_pos_); + SetErrorCode(JSON_BAD_ROOT_ELEMENT_TYPE, json_pos_); return NULL; } @@ -234,7 +273,7 @@ Value* JSONReader::BuildValue(bool is_root) { // consumers need the parsing leniency, so handle accordingly. if (token.type == Token::ARRAY_END) { if (!allow_trailing_comma_) { - SetErrorMessage(kTrailingComma, json_pos_); + SetErrorCode(JSON_TRAILING_COMMA, json_pos_); return NULL; } // Trailing comma OK, stop parsing the Array. @@ -259,7 +298,7 @@ Value* JSONReader::BuildValue(bool is_root) { node.reset(new DictionaryValue); while (token.type != Token::OBJECT_END) { if (token.type != Token::STRING) { - SetErrorMessage(kUnquotedDictionaryKey, json_pos_); + SetErrorCode(JSON_UNQUOTED_DICTIONARY_KEY, json_pos_); return NULL; } scoped_ptr<Value> dict_key_value(DecodeString(token)); @@ -294,7 +333,7 @@ Value* JSONReader::BuildValue(bool is_root) { // consumers need the parsing leniency, so handle accordingly. if (token.type == Token::OBJECT_END) { if (!allow_trailing_comma_) { - SetErrorMessage(kTrailingComma, json_pos_); + SetErrorCode(JSON_TRAILING_COMMA, json_pos_); return NULL; } // Trailing comma OK, stop parsing the Object. @@ -384,13 +423,13 @@ JSONReader::Token JSONReader::ParseStringToken() { switch (c) { case 'x': if (!ReadHexDigits(token, 2)) { - SetErrorMessage(kInvalidEscape, json_pos_ + token.length); + SetErrorCode(JSON_INVALID_ESCAPE, json_pos_ + token.length); return kInvalidToken; } break; case 'u': if (!ReadHexDigits(token, 4)) { - SetErrorMessage(kInvalidEscape, json_pos_ + token.length); + SetErrorCode(JSON_INVALID_ESCAPE, json_pos_ + token.length); return kInvalidToken; } break; @@ -405,7 +444,7 @@ JSONReader::Token JSONReader::ParseStringToken() { case '"': break; default: - SetErrorMessage(kInvalidEscape, json_pos_ + token.length); + SetErrorCode(JSON_INVALID_ESCAPE, json_pos_ + token.length); return kInvalidToken; } } else if ('"' == c) { @@ -617,8 +656,8 @@ bool JSONReader::EatComment() { return true; } -void JSONReader::SetErrorMessage(const char* description, - const wchar_t* error_pos) { +void JSONReader::SetErrorCode(JsonParseError error, + const wchar_t* error_pos) { int line_number = 1; int column_number = 1; @@ -637,7 +676,9 @@ void JSONReader::SetErrorMessage(const char* description, } } - error_message_ = FormatErrorMessage(line_number, column_number, description); + error_line_ = line_number; + error_col_ = column_number; + error_code_ = error; } } // namespace base |