| 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 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 460 } |
| 461 previous_char = next_char; | 461 previous_char = next_char; |
| 462 } | 462 } |
| 463 | 463 |
| 464 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. | 464 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. |
| 465 } | 465 } |
| 466 | 466 |
| 467 return false; | 467 return false; |
| 468 } | 468 } |
| 469 | 469 |
| 470 Value* JSONParser::ParseNextToken() { | 470 std::unique_ptr<Value> JSONParser::ParseNextToken() { |
| 471 return ParseToken(GetNextToken()); | 471 return ParseToken(GetNextToken()); |
| 472 } | 472 } |
| 473 | 473 |
| 474 Value* JSONParser::ParseToken(Token token) { | 474 std::unique_ptr<Value> JSONParser::ParseToken(Token token) { |
| 475 switch (token) { | 475 switch (token) { |
| 476 case T_OBJECT_BEGIN: | 476 case T_OBJECT_BEGIN: |
| 477 return ConsumeDictionary(); | 477 return ConsumeDictionary(); |
| 478 case T_ARRAY_BEGIN: | 478 case T_ARRAY_BEGIN: |
| 479 return ConsumeList(); | 479 return ConsumeList(); |
| 480 case T_STRING: | 480 case T_STRING: |
| 481 return ConsumeString(); | 481 return ConsumeString(); |
| 482 case T_NUMBER: | 482 case T_NUMBER: |
| 483 return ConsumeNumber(); | 483 return ConsumeNumber(); |
| 484 case T_BOOL_TRUE: | 484 case T_BOOL_TRUE: |
| 485 case T_BOOL_FALSE: | 485 case T_BOOL_FALSE: |
| 486 case T_NULL: | 486 case T_NULL: |
| 487 return ConsumeLiteral(); | 487 return ConsumeLiteral(); |
| 488 default: | 488 default: |
| 489 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 489 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 490 return nullptr; | 490 return nullptr; |
| 491 } | 491 } |
| 492 } | 492 } |
| 493 | 493 |
| 494 Value* JSONParser::ConsumeDictionary() { | 494 std::unique_ptr<Value> JSONParser::ConsumeDictionary() { |
| 495 if (*pos_ != '{') { | 495 if (*pos_ != '{') { |
| 496 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 496 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 497 return nullptr; | 497 return nullptr; |
| 498 } | 498 } |
| 499 | 499 |
| 500 StackMarker depth_check(&stack_depth_); | 500 StackMarker depth_check(&stack_depth_); |
| 501 if (depth_check.IsTooDeep()) { | 501 if (depth_check.IsTooDeep()) { |
| 502 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 502 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
| 503 return nullptr; | 503 return nullptr; |
| 504 } | 504 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 522 // Read the separator. | 522 // Read the separator. |
| 523 NextChar(); | 523 NextChar(); |
| 524 token = GetNextToken(); | 524 token = GetNextToken(); |
| 525 if (token != T_OBJECT_PAIR_SEPARATOR) { | 525 if (token != T_OBJECT_PAIR_SEPARATOR) { |
| 526 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 526 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 527 return nullptr; | 527 return nullptr; |
| 528 } | 528 } |
| 529 | 529 |
| 530 // The next token is the value. Ownership transfers to |dict|. | 530 // The next token is the value. Ownership transfers to |dict|. |
| 531 NextChar(); | 531 NextChar(); |
| 532 Value* value = ParseNextToken(); | 532 std::unique_ptr<Value> value = ParseNextToken(); |
| 533 if (!value) { | 533 if (!value) { |
| 534 // ReportError from deeper level. | 534 // ReportError from deeper level. |
| 535 return nullptr; | 535 return nullptr; |
| 536 } | 536 } |
| 537 | 537 |
| 538 dict->SetWithoutPathExpansion(key.AsString(), value); | 538 dict->SetWithoutPathExpansion(key.AsString(), std::move(value)); |
| 539 | 539 |
| 540 NextChar(); | 540 NextChar(); |
| 541 token = GetNextToken(); | 541 token = GetNextToken(); |
| 542 if (token == T_LIST_SEPARATOR) { | 542 if (token == T_LIST_SEPARATOR) { |
| 543 NextChar(); | 543 NextChar(); |
| 544 token = GetNextToken(); | 544 token = GetNextToken(); |
| 545 if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { | 545 if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { |
| 546 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); | 546 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); |
| 547 return nullptr; | 547 return nullptr; |
| 548 } | 548 } |
| 549 } else if (token != T_OBJECT_END) { | 549 } else if (token != T_OBJECT_END) { |
| 550 ReportError(JSONReader::JSON_SYNTAX_ERROR, 0); | 550 ReportError(JSONReader::JSON_SYNTAX_ERROR, 0); |
| 551 return nullptr; | 551 return nullptr; |
| 552 } | 552 } |
| 553 } | 553 } |
| 554 | 554 |
| 555 return dict.release(); | 555 return std::move(dict); |
| 556 } | 556 } |
| 557 | 557 |
| 558 Value* JSONParser::ConsumeList() { | 558 std::unique_ptr<Value> JSONParser::ConsumeList() { |
| 559 if (*pos_ != '[') { | 559 if (*pos_ != '[') { |
| 560 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 560 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 561 return nullptr; | 561 return nullptr; |
| 562 } | 562 } |
| 563 | 563 |
| 564 StackMarker depth_check(&stack_depth_); | 564 StackMarker depth_check(&stack_depth_); |
| 565 if (depth_check.IsTooDeep()) { | 565 if (depth_check.IsTooDeep()) { |
| 566 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); | 566 ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1); |
| 567 return nullptr; | 567 return nullptr; |
| 568 } | 568 } |
| 569 | 569 |
| 570 std::unique_ptr<ListValue> list(new ListValue); | 570 std::unique_ptr<ListValue> list(new ListValue); |
| 571 | 571 |
| 572 NextChar(); | 572 NextChar(); |
| 573 Token token = GetNextToken(); | 573 Token token = GetNextToken(); |
| 574 while (token != T_ARRAY_END) { | 574 while (token != T_ARRAY_END) { |
| 575 Value* item = ParseToken(token); | 575 std::unique_ptr<Value> item = ParseToken(token); |
| 576 if (!item) { | 576 if (!item) { |
| 577 // ReportError from deeper level. | 577 // ReportError from deeper level. |
| 578 return nullptr; | 578 return nullptr; |
| 579 } | 579 } |
| 580 | 580 |
| 581 list->Append(item); | 581 list->Append(std::move(item)); |
| 582 | 582 |
| 583 NextChar(); | 583 NextChar(); |
| 584 token = GetNextToken(); | 584 token = GetNextToken(); |
| 585 if (token == T_LIST_SEPARATOR) { | 585 if (token == T_LIST_SEPARATOR) { |
| 586 NextChar(); | 586 NextChar(); |
| 587 token = GetNextToken(); | 587 token = GetNextToken(); |
| 588 if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { | 588 if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) { |
| 589 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); | 589 ReportError(JSONReader::JSON_TRAILING_COMMA, 1); |
| 590 return nullptr; | 590 return nullptr; |
| 591 } | 591 } |
| 592 } else if (token != T_ARRAY_END) { | 592 } else if (token != T_ARRAY_END) { |
| 593 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 593 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 594 return nullptr; | 594 return nullptr; |
| 595 } | 595 } |
| 596 } | 596 } |
| 597 | 597 |
| 598 return list.release(); | 598 return std::move(list); |
| 599 } | 599 } |
| 600 | 600 |
| 601 Value* JSONParser::ConsumeString() { | 601 std::unique_ptr<Value> JSONParser::ConsumeString() { |
| 602 StringBuilder string; | 602 StringBuilder string; |
| 603 if (!ConsumeStringRaw(&string)) | 603 if (!ConsumeStringRaw(&string)) |
| 604 return nullptr; | 604 return nullptr; |
| 605 | 605 |
| 606 // Create the Value representation, using a hidden root, if configured | 606 // Create the Value representation, using a hidden root, if configured |
| 607 // to do so, and if the string can be represented by StringPiece. | 607 // to do so, and if the string can be represented by StringPiece. |
| 608 if (string.CanBeStringPiece() && !(options_ & JSON_DETACHABLE_CHILDREN)) | 608 if (string.CanBeStringPiece() && !(options_ & JSON_DETACHABLE_CHILDREN)) |
| 609 return new JSONStringValue(string.AsStringPiece()); | 609 return base::MakeUnique<JSONStringValue>(string.AsStringPiece()); |
| 610 | 610 |
| 611 if (string.CanBeStringPiece()) | 611 if (string.CanBeStringPiece()) |
| 612 string.Convert(); | 612 string.Convert(); |
| 613 return new StringValue(string.AsString()); | 613 return base::MakeUnique<StringValue>(string.AsString()); |
| 614 } | 614 } |
| 615 | 615 |
| 616 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { | 616 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { |
| 617 if (*pos_ != '"') { | 617 if (*pos_ != '"') { |
| 618 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 618 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 619 return false; | 619 return false; |
| 620 } | 620 } |
| 621 | 621 |
| 622 // StringBuilder will internally build a StringPiece unless a UTF-16 | 622 // StringBuilder will internally build a StringPiece unless a UTF-16 |
| 623 // conversion occurs, at which point it will perform a copy into a | 623 // conversion occurs, at which point it will perform a copy into a |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 char utf8_units[4] = { 0 }; | 820 char utf8_units[4] = { 0 }; |
| 821 int offset = 0; | 821 int offset = 0; |
| 822 CBU8_APPEND_UNSAFE(utf8_units, offset, point); | 822 CBU8_APPEND_UNSAFE(utf8_units, offset, point); |
| 823 dest->Convert(); | 823 dest->Convert(); |
| 824 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be | 824 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be |
| 825 // zero terminated at this point. |offset| contains the correct length. | 825 // zero terminated at this point. |offset| contains the correct length. |
| 826 dest->AppendString(std::string(utf8_units, offset)); | 826 dest->AppendString(std::string(utf8_units, offset)); |
| 827 } | 827 } |
| 828 } | 828 } |
| 829 | 829 |
| 830 Value* JSONParser::ConsumeNumber() { | 830 std::unique_ptr<Value> JSONParser::ConsumeNumber() { |
| 831 const char* num_start = pos_; | 831 const char* num_start = pos_; |
| 832 const int start_index = index_; | 832 const int start_index = index_; |
| 833 int end_index = start_index; | 833 int end_index = start_index; |
| 834 | 834 |
| 835 if (*pos_ == '-') | 835 if (*pos_ == '-') |
| 836 NextChar(); | 836 NextChar(); |
| 837 | 837 |
| 838 if (!ReadInt(false)) { | 838 if (!ReadInt(false)) { |
| 839 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 839 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 840 return nullptr; | 840 return nullptr; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 return nullptr; | 885 return nullptr; |
| 886 } | 886 } |
| 887 | 887 |
| 888 pos_ = exit_pos; | 888 pos_ = exit_pos; |
| 889 index_ = exit_index; | 889 index_ = exit_index; |
| 890 | 890 |
| 891 StringPiece num_string(num_start, end_index - start_index); | 891 StringPiece num_string(num_start, end_index - start_index); |
| 892 | 892 |
| 893 int num_int; | 893 int num_int; |
| 894 if (StringToInt(num_string, &num_int)) | 894 if (StringToInt(num_string, &num_int)) |
| 895 return new FundamentalValue(num_int); | 895 return base::MakeUnique<FundamentalValue>(num_int); |
| 896 | 896 |
| 897 double num_double; | 897 double num_double; |
| 898 if (StringToDouble(num_string.as_string(), &num_double) && | 898 if (StringToDouble(num_string.as_string(), &num_double) && |
| 899 std::isfinite(num_double)) { | 899 std::isfinite(num_double)) { |
| 900 return new FundamentalValue(num_double); | 900 return base::MakeUnique<FundamentalValue>(num_double); |
| 901 } | 901 } |
| 902 | 902 |
| 903 return nullptr; | 903 return nullptr; |
| 904 } | 904 } |
| 905 | 905 |
| 906 bool JSONParser::ReadInt(bool allow_leading_zeros) { | 906 bool JSONParser::ReadInt(bool allow_leading_zeros) { |
| 907 char first = *pos_; | 907 char first = *pos_; |
| 908 int len = 0; | 908 int len = 0; |
| 909 | 909 |
| 910 char c = first; | 910 char c = first; |
| 911 while (CanConsume(1) && IsAsciiDigit(c)) { | 911 while (CanConsume(1) && IsAsciiDigit(c)) { |
| 912 c = *NextChar(); | 912 c = *NextChar(); |
| 913 ++len; | 913 ++len; |
| 914 } | 914 } |
| 915 | 915 |
| 916 if (len == 0) | 916 if (len == 0) |
| 917 return false; | 917 return false; |
| 918 | 918 |
| 919 if (!allow_leading_zeros && len > 1 && first == '0') | 919 if (!allow_leading_zeros && len > 1 && first == '0') |
| 920 return false; | 920 return false; |
| 921 | 921 |
| 922 return true; | 922 return true; |
| 923 } | 923 } |
| 924 | 924 |
| 925 Value* JSONParser::ConsumeLiteral() { | 925 std::unique_ptr<Value> JSONParser::ConsumeLiteral() { |
| 926 switch (*pos_) { | 926 switch (*pos_) { |
| 927 case 't': { | 927 case 't': { |
| 928 const char kTrueLiteral[] = "true"; | 928 const char kTrueLiteral[] = "true"; |
| 929 const int kTrueLen = static_cast<int>(strlen(kTrueLiteral)); | 929 const int kTrueLen = static_cast<int>(strlen(kTrueLiteral)); |
| 930 if (!CanConsume(kTrueLen - 1) || | 930 if (!CanConsume(kTrueLen - 1) || |
| 931 !StringsAreEqual(pos_, kTrueLiteral, kTrueLen)) { | 931 !StringsAreEqual(pos_, kTrueLiteral, kTrueLen)) { |
| 932 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 932 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 933 return nullptr; | 933 return nullptr; |
| 934 } | 934 } |
| 935 NextNChars(kTrueLen - 1); | 935 NextNChars(kTrueLen - 1); |
| 936 return new FundamentalValue(true); | 936 return base::MakeUnique<FundamentalValue>(true); |
| 937 } | 937 } |
| 938 case 'f': { | 938 case 'f': { |
| 939 const char kFalseLiteral[] = "false"; | 939 const char kFalseLiteral[] = "false"; |
| 940 const int kFalseLen = static_cast<int>(strlen(kFalseLiteral)); | 940 const int kFalseLen = static_cast<int>(strlen(kFalseLiteral)); |
| 941 if (!CanConsume(kFalseLen - 1) || | 941 if (!CanConsume(kFalseLen - 1) || |
| 942 !StringsAreEqual(pos_, kFalseLiteral, kFalseLen)) { | 942 !StringsAreEqual(pos_, kFalseLiteral, kFalseLen)) { |
| 943 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 943 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 944 return nullptr; | 944 return nullptr; |
| 945 } | 945 } |
| 946 NextNChars(kFalseLen - 1); | 946 NextNChars(kFalseLen - 1); |
| 947 return new FundamentalValue(false); | 947 return base::MakeUnique<FundamentalValue>(false); |
| 948 } | 948 } |
| 949 case 'n': { | 949 case 'n': { |
| 950 const char kNullLiteral[] = "null"; | 950 const char kNullLiteral[] = "null"; |
| 951 const int kNullLen = static_cast<int>(strlen(kNullLiteral)); | 951 const int kNullLen = static_cast<int>(strlen(kNullLiteral)); |
| 952 if (!CanConsume(kNullLen - 1) || | 952 if (!CanConsume(kNullLen - 1) || |
| 953 !StringsAreEqual(pos_, kNullLiteral, kNullLen)) { | 953 !StringsAreEqual(pos_, kNullLiteral, kNullLen)) { |
| 954 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); | 954 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 955 return nullptr; | 955 return nullptr; |
| 956 } | 956 } |
| 957 NextNChars(kNullLen - 1); | 957 NextNChars(kNullLen - 1); |
| 958 return Value::CreateNullValue().release(); | 958 return Value::CreateNullValue(); |
| 959 } | 959 } |
| 960 default: | 960 default: |
| 961 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 961 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 962 return nullptr; | 962 return nullptr; |
| 963 } | 963 } |
| 964 } | 964 } |
| 965 | 965 |
| 966 // static | 966 // static |
| 967 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) { | 967 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) { |
| 968 return strncmp(one, two, len) == 0; | 968 return strncmp(one, two, len) == 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 980 const std::string& description) { | 980 const std::string& description) { |
| 981 if (line || column) { | 981 if (line || column) { |
| 982 return StringPrintf("Line: %i, column: %i, %s", | 982 return StringPrintf("Line: %i, column: %i, %s", |
| 983 line, column, description.c_str()); | 983 line, column, description.c_str()); |
| 984 } | 984 } |
| 985 return description; | 985 return description; |
| 986 } | 986 } |
| 987 | 987 |
| 988 } // namespace internal | 988 } // namespace internal |
| 989 } // namespace base | 989 } // namespace base |
| OLD | NEW |