Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: base/json/json_parser.cc

Issue 2712013003: Fix several potential buffer over-read errors in JSONParser::ConsumeNumber. (Closed)
Patch Set: Fix ReadInt Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/json/json_parser_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 if (*pos_ == '-') 673 if (*pos_ == '-')
674 NextChar(); 674 NextChar();
675 675
676 if (!ReadInt(false)) { 676 if (!ReadInt(false)) {
677 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); 677 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
678 return nullptr; 678 return nullptr;
679 } 679 }
680 end_index = index_; 680 end_index = index_;
681 681
682 // The optional fraction part. 682 // The optional fraction part.
683 if (*pos_ == '.') { 683 if (CanConsume(1) && *pos_ == '.') {
684 if (!CanConsume(1)) {
685 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
686 return nullptr;
687 }
688 NextChar(); 684 NextChar();
689 if (!ReadInt(true)) { 685 if (!ReadInt(true)) {
690 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); 686 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
691 return nullptr; 687 return nullptr;
692 } 688 }
693 end_index = index_; 689 end_index = index_;
694 } 690 }
695 691
696 // Optional exponent part. 692 // Optional exponent part.
697 if (*pos_ == 'e' || *pos_ == 'E') { 693 if (CanConsume(1) && (*pos_ == 'e' || *pos_ == 'E')) {
698 NextChar(); 694 NextChar();
699 if (*pos_ == '-' || *pos_ == '+') 695 if (!CanConsume(1)) {
696 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
697 return nullptr;
698 }
699 if (*pos_ == '-' || *pos_ == '+') {
700 NextChar(); 700 NextChar();
701 }
701 if (!ReadInt(true)) { 702 if (!ReadInt(true)) {
702 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); 703 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
703 return nullptr; 704 return nullptr;
704 } 705 }
705 end_index = index_; 706 end_index = index_;
706 } 707 }
707 708
708 // ReadInt is greedy because numbers have no easily detectable sentinel, 709 // ReadInt is greedy because numbers have no easily detectable sentinel,
709 // so save off where the parser should be on exit (see Consume invariant at 710 // so save off where the parser should be on exit (see Consume invariant at
710 // the top of the header), then make sure the next token is one which is 711 // the top of the header), then make sure the next token is one which is
(...skipping 24 matching lines...) Expand all
735 double num_double; 736 double num_double;
736 if (StringToDouble(num_string.as_string(), &num_double) && 737 if (StringToDouble(num_string.as_string(), &num_double) &&
737 std::isfinite(num_double)) { 738 std::isfinite(num_double)) {
738 return base::MakeUnique<FundamentalValue>(num_double); 739 return base::MakeUnique<FundamentalValue>(num_double);
739 } 740 }
740 741
741 return nullptr; 742 return nullptr;
742 } 743 }
743 744
744 bool JSONParser::ReadInt(bool allow_leading_zeros) { 745 bool JSONParser::ReadInt(bool allow_leading_zeros) {
745 char first = *pos_; 746 size_t len = 0;
746 int len = 0; 747 char first = 0;
747 748
748 char c = first; 749 while (CanConsume(1)) {
749 while (CanConsume(1) && IsAsciiDigit(c)) { 750 if (!IsAsciiDigit(*pos_))
750 c = *NextChar(); 751 break;
752
753 if (len == 0)
754 first = *pos_;
755
751 ++len; 756 ++len;
757 NextChar();
752 } 758 }
753 759
754 if (len == 0) 760 if (len == 0)
755 return false; 761 return false;
756 762
757 if (!allow_leading_zeros && len > 1 && first == '0') 763 if (!allow_leading_zeros && len > 1 && first == '0')
758 return false; 764 return false;
759 765
760 return true; 766 return true;
761 } 767 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 const std::string& description) { 824 const std::string& description) {
819 if (line || column) { 825 if (line || column) {
820 return StringPrintf("Line: %i, column: %i, %s", 826 return StringPrintf("Line: %i, column: %i, %s",
821 line, column, description.c_str()); 827 line, column, description.c_str());
822 } 828 }
823 return description; 829 return description;
824 } 830 }
825 831
826 } // namespace internal 832 } // namespace internal
827 } // namespace base 833 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/json/json_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698