| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/json/json_parser.h" | 5 #include "base/json/json_parser.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" |
| 10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
| 13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 15 #include "base/strings/utf_string_conversion_utils.h" | 16 #include "base/strings/utf_string_conversion_utils.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/third_party/icu/icu_utf.h" | 18 #include "base/third_party/icu/icu_utf.h" |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 | 20 |
| 20 namespace base { | 21 namespace base { |
| 21 namespace internal { | 22 namespace internal { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 const int kStackMaxDepth = 100; | 26 const int kStackMaxDepth = 100; |
| 26 | 27 |
| 27 const int32 kExtendedASCIIStart = 0x80; | 28 const int32_t kExtendedASCIIStart = 0x80; |
| 28 | 29 |
| 29 // This and the class below are used to own the JSON input string for when | 30 // This and the class below are used to own the JSON input string for when |
| 30 // string tokens are stored as StringPiece instead of std::string. This | 31 // string tokens are stored as StringPiece instead of std::string. This |
| 31 // optimization avoids about 2/3rds of string memory copies. The constructor | 32 // optimization avoids about 2/3rds of string memory copies. The constructor |
| 32 // takes ownership of the input string. The real root value is Swap()ed into | 33 // takes ownership of the input string. The real root value is Swap()ed into |
| 33 // the new instance. | 34 // the new instance. |
| 34 class DictionaryHiddenRootValue : public DictionaryValue { | 35 class DictionaryHiddenRootValue : public DictionaryValue { |
| 35 public: | 36 public: |
| 36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { | 37 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { |
| 37 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); | 38 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 index_last_line_ = 0; | 221 index_last_line_ = 0; |
| 221 | 222 |
| 222 error_code_ = JSONReader::JSON_NO_ERROR; | 223 error_code_ = JSONReader::JSON_NO_ERROR; |
| 223 error_line_ = 0; | 224 error_line_ = 0; |
| 224 error_column_ = 0; | 225 error_column_ = 0; |
| 225 | 226 |
| 226 // When the input JSON string starts with a UTF-8 Byte-Order-Mark | 227 // When the input JSON string starts with a UTF-8 Byte-Order-Mark |
| 227 // <0xEF 0xBB 0xBF>, advance the start position to avoid the | 228 // <0xEF 0xBB 0xBF>, advance the start position to avoid the |
| 228 // ParseNextToken function mis-treating a Unicode BOM as an invalid | 229 // ParseNextToken function mis-treating a Unicode BOM as an invalid |
| 229 // character and returning NULL. | 230 // character and returning NULL. |
| 230 if (CanConsume(3) && static_cast<uint8>(*pos_) == 0xEF && | 231 if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF && |
| 231 static_cast<uint8>(*(pos_ + 1)) == 0xBB && | 232 static_cast<uint8_t>(*(pos_ + 1)) == 0xBB && |
| 232 static_cast<uint8>(*(pos_ + 2)) == 0xBF) { | 233 static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) { |
| 233 NextNChars(3); | 234 NextNChars(3); |
| 234 } | 235 } |
| 235 | 236 |
| 236 // Parse the first and any nested tokens. | 237 // Parse the first and any nested tokens. |
| 237 scoped_ptr<Value> root(ParseNextToken()); | 238 scoped_ptr<Value> root(ParseNextToken()); |
| 238 if (!root.get()) | 239 if (!root.get()) |
| 239 return NULL; | 240 return NULL; |
| 240 | 241 |
| 241 // Make sure the input stream is at an end. | 242 // Make sure the input stream is at an end. |
| 242 if (GetNextToken() != T_END_OF_INPUT) { | 243 if (GetNextToken() != T_END_OF_INPUT) { |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 607 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 607 return false; | 608 return false; |
| 608 } | 609 } |
| 609 | 610 |
| 610 // StringBuilder will internally build a StringPiece unless a UTF-16 | 611 // StringBuilder will internally build a StringPiece unless a UTF-16 |
| 611 // conversion occurs, at which point it will perform a copy into a | 612 // conversion occurs, at which point it will perform a copy into a |
| 612 // std::string. | 613 // std::string. |
| 613 StringBuilder string(NextChar()); | 614 StringBuilder string(NextChar()); |
| 614 | 615 |
| 615 int length = end_pos_ - start_pos_; | 616 int length = end_pos_ - start_pos_; |
| 616 int32 next_char = 0; | 617 int32_t next_char = 0; |
| 617 | 618 |
| 618 while (CanConsume(1)) { | 619 while (CanConsume(1)) { |
| 619 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. | 620 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. |
| 620 CBU8_NEXT(start_pos_, index_, length, next_char); | 621 CBU8_NEXT(start_pos_, index_, length, next_char); |
| 621 if (next_char < 0 || !IsValidCharacter(next_char)) { | 622 if (next_char < 0 || !IsValidCharacter(next_char)) { |
| 622 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); | 623 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); |
| 623 return false; | 624 return false; |
| 624 } | 625 } |
| 625 | 626 |
| 626 // If this character is an escape sequence... | 627 // If this character is an escape sequence... |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 int code_unit16_low = 0; | 768 int code_unit16_low = 0; |
| 768 if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_low)) | 769 if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_low)) |
| 769 return false; | 770 return false; |
| 770 | 771 |
| 771 NextNChars(3); | 772 NextNChars(3); |
| 772 | 773 |
| 773 if (!CBU16_IS_TRAIL(code_unit16_low)) { | 774 if (!CBU16_IS_TRAIL(code_unit16_low)) { |
| 774 return false; | 775 return false; |
| 775 } | 776 } |
| 776 | 777 |
| 777 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high, | 778 uint32_t code_point = |
| 778 code_unit16_low); | 779 CBU16_GET_SUPPLEMENTARY(code_unit16_high, code_unit16_low); |
| 779 if (!IsValidCharacter(code_point)) | 780 if (!IsValidCharacter(code_point)) |
| 780 return false; | 781 return false; |
| 781 | 782 |
| 782 offset = 0; | 783 offset = 0; |
| 783 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); | 784 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); |
| 784 } else { | 785 } else { |
| 785 // Not a surrogate. | 786 // Not a surrogate. |
| 786 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); | 787 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); |
| 787 if (!IsValidCharacter(code_unit16_high)) | 788 if (!IsValidCharacter(code_unit16_high)) |
| 788 return false; | 789 return false; |
| 789 | 790 |
| 790 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); | 791 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); |
| 791 } | 792 } |
| 792 | 793 |
| 793 dest_string->append(code_unit8); | 794 dest_string->append(code_unit8); |
| 794 return true; | 795 return true; |
| 795 } | 796 } |
| 796 | 797 |
| 797 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) { | 798 void JSONParser::DecodeUTF8(const int32_t& point, StringBuilder* dest) { |
| 798 DCHECK(IsValidCharacter(point)); | 799 DCHECK(IsValidCharacter(point)); |
| 799 | 800 |
| 800 // Anything outside of the basic ASCII plane will need to be decoded from | 801 // Anything outside of the basic ASCII plane will need to be decoded from |
| 801 // int32 to a multi-byte sequence. | 802 // int32_t to a multi-byte sequence. |
| 802 if (point < kExtendedASCIIStart) { | 803 if (point < kExtendedASCIIStart) { |
| 803 dest->Append(static_cast<char>(point)); | 804 dest->Append(static_cast<char>(point)); |
| 804 } else { | 805 } else { |
| 805 char utf8_units[4] = { 0 }; | 806 char utf8_units[4] = { 0 }; |
| 806 int offset = 0; | 807 int offset = 0; |
| 807 CBU8_APPEND_UNSAFE(utf8_units, offset, point); | 808 CBU8_APPEND_UNSAFE(utf8_units, offset, point); |
| 808 dest->Convert(); | 809 dest->Convert(); |
| 809 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be | 810 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be |
| 810 // zero terminated at this point. |offset| contains the correct length. | 811 // zero terminated at this point. |offset| contains the correct length. |
| 811 dest->AppendString(std::string(utf8_units, offset)); | 812 dest->AppendString(std::string(utf8_units, offset)); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 const std::string& description) { | 966 const std::string& description) { |
| 966 if (line || column) { | 967 if (line || column) { |
| 967 return StringPrintf("Line: %i, column: %i, %s", | 968 return StringPrintf("Line: %i, column: %i, %s", |
| 968 line, column, description.c_str()); | 969 line, column, description.c_str()); |
| 969 } | 970 } |
| 970 return description; | 971 return description; |
| 971 } | 972 } |
| 972 | 973 |
| 973 } // namespace internal | 974 } // namespace internal |
| 974 } // namespace base | 975 } // namespace base |
| OLD | NEW |