Home | History | Annotate | Download | only in json
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/json/json_parser.h"
      6 
      7 #include <cmath>
      8 #include <utility>
      9 
     10 #include "base/logging.h"
     11 #include "base/macros.h"
     12 #include "base/memory/ptr_util.h"
     13 #include "base/strings/string_number_conversions.h"
     14 #include "base/strings/string_piece.h"
     15 #include "base/strings/string_util.h"
     16 #include "base/strings/stringprintf.h"
     17 #include "base/strings/utf_string_conversion_utils.h"
     18 #include "base/strings/utf_string_conversions.h"
     19 #include "base/third_party/icu/icu_utf.h"
     20 #include "base/values.h"
     21 
     22 namespace base {
     23 namespace internal {
     24 
     25 namespace {
     26 
     27 // Chosen to support 99.9% of documents found in the wild late 2016.
     28 // http://crbug.com/673263
     29 const int kStackMaxDepth = 200;
     30 
     31 const int32_t kExtendedASCIIStart = 0x80;
     32 
     33 // Simple class that checks for maximum recursion/"stack overflow."
     34 class StackMarker {
     35  public:
     36   explicit StackMarker(int* depth) : depth_(depth) {
     37     ++(*depth_);
     38     DCHECK_LE(*depth_, kStackMaxDepth);
     39   }
     40   ~StackMarker() {
     41     --(*depth_);
     42   }
     43 
     44   bool IsTooDeep() const {
     45     return *depth_ >= kStackMaxDepth;
     46   }
     47 
     48  private:
     49   int* const depth_;
     50 
     51   DISALLOW_COPY_AND_ASSIGN(StackMarker);
     52 };
     53 
     54 }  // namespace
     55 
     56 // This is U+FFFD.
     57 const char kUnicodeReplacementString[] = "\xEF\xBF\xBD";
     58 
     59 JSONParser::JSONParser(int options)
     60     : options_(options),
     61       start_pos_(nullptr),
     62       pos_(nullptr),
     63       end_pos_(nullptr),
     64       index_(0),
     65       stack_depth_(0),
     66       line_number_(0),
     67       index_last_line_(0),
     68       error_code_(JSONReader::JSON_NO_ERROR),
     69       error_line_(0),
     70       error_column_(0) {
     71 }
     72 
     73 JSONParser::~JSONParser() {
     74 }
     75 
     76 std::unique_ptr<Value> JSONParser::Parse(StringPiece input) {
     77   start_pos_ = input.data();
     78   pos_ = start_pos_;
     79   end_pos_ = start_pos_ + input.length();
     80   index_ = 0;
     81   line_number_ = 1;
     82   index_last_line_ = 0;
     83 
     84   error_code_ = JSONReader::JSON_NO_ERROR;
     85   error_line_ = 0;
     86   error_column_ = 0;
     87 
     88   // When the input JSON string starts with a UTF-8 Byte-Order-Mark
     89   // <0xEF 0xBB 0xBF>, advance the start position to avoid the
     90   // ParseNextToken function mis-treating a Unicode BOM as an invalid
     91   // character and returning NULL.
     92   if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF &&
     93       static_cast<uint8_t>(*(pos_ + 1)) == 0xBB &&
     94       static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) {
     95     NextNChars(3);
     96   }
     97 
     98   // Parse the first and any nested tokens.
     99   std::unique_ptr<Value> root(ParseNextToken());
    100   if (!root)
    101     return nullptr;
    102 
    103   // Make sure the input stream is at an end.
    104   if (GetNextToken() != T_END_OF_INPUT) {
    105     if (!CanConsume(1) || (NextChar() && GetNextToken() != T_END_OF_INPUT)) {
    106       ReportError(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, 1);
    107       return nullptr;
    108     }
    109   }
    110 
    111   return root;
    112 }
    113 
    114 JSONReader::JsonParseError JSONParser::error_code() const {
    115   return error_code_;
    116 }
    117 
    118 std::string JSONParser::GetErrorMessage() const {
    119   return FormatErrorMessage(error_line_, error_column_,
    120       JSONReader::ErrorCodeToString(error_code_));
    121 }
    122 
    123 int JSONParser::error_line() const {
    124   return error_line_;
    125 }
    126 
    127 int JSONParser::error_column() const {
    128   return error_column_;
    129 }
    130 
    131 // StringBuilder ///////////////////////////////////////////////////////////////
    132 
    133 JSONParser::StringBuilder::StringBuilder() : StringBuilder(nullptr) {}
    134 
    135 JSONParser::StringBuilder::StringBuilder(const char* pos)
    136     : pos_(pos), length_(0), has_string_(false) {}
    137 
    138 JSONParser::StringBuilder::~StringBuilder() {
    139   if (has_string_)
    140     string_.Destroy();
    141 }
    142 
    143 void JSONParser::StringBuilder::operator=(StringBuilder&& other) {
    144   pos_ = other.pos_;
    145   length_ = other.length_;
    146   has_string_ = other.has_string_;
    147   if (has_string_)
    148     string_.InitFromMove(std::move(other.string_));
    149 }
    150 
    151 void JSONParser::StringBuilder::Append(const char& c) {
    152   DCHECK_GE(c, 0);
    153   DCHECK_LT(static_cast<unsigned char>(c), 128);
    154 
    155   if (has_string_)
    156     string_->push_back(c);
    157   else
    158     ++length_;
    159 }
    160 
    161 void JSONParser::StringBuilder::AppendString(const char* str, size_t len) {
    162   DCHECK(has_string_);
    163   string_->append(str, len);
    164 }
    165 
    166 void JSONParser::StringBuilder::Convert() {
    167   if (has_string_)
    168     return;
    169 
    170   has_string_ = true;
    171   string_.Init(pos_, length_);
    172 }
    173 
    174 StringPiece JSONParser::StringBuilder::AsStringPiece() {
    175   if (has_string_)
    176     return StringPiece(*string_);
    177   return StringPiece(pos_, length_);
    178 }
    179 
    180 const std::string& JSONParser::StringBuilder::AsString() {
    181   if (!has_string_)
    182     Convert();
    183   return *string_;
    184 }
    185 
    186 std::string JSONParser::StringBuilder::DestructiveAsString() {
    187   if (has_string_)
    188     return std::move(*string_);
    189   return std::string(pos_, length_);
    190 }
    191 
    192 // JSONParser private //////////////////////////////////////////////////////////
    193 
    194 inline bool JSONParser::CanConsume(int length) {
    195   return pos_ + length <= end_pos_;
    196 }
    197 
    198 const char* JSONParser::NextChar() {
    199   DCHECK(CanConsume(1));
    200   ++index_;
    201   ++pos_;
    202   return pos_;
    203 }
    204 
    205 void JSONParser::NextNChars(int n) {
    206   DCHECK(CanConsume(n));
    207   index_ += n;
    208   pos_ += n;
    209 }
    210 
    211 JSONParser::Token JSONParser::GetNextToken() {
    212   EatWhitespaceAndComments();
    213   if (!CanConsume(1))
    214     return T_END_OF_INPUT;
    215 
    216   switch (*pos_) {
    217     case '{':
    218       return T_OBJECT_BEGIN;
    219     case '}':
    220       return T_OBJECT_END;
    221     case '[':
    222       return T_ARRAY_BEGIN;
    223     case ']':
    224       return T_ARRAY_END;
    225     case '"':
    226       return T_STRING;
    227     case '0':
    228     case '1':
    229     case '2':
    230     case '3':
    231     case '4':
    232     case '5':
    233     case '6':
    234     case '7':
    235     case '8':
    236     case '9':
    237     case '-':
    238       return T_NUMBER;
    239     case 't':
    240       return T_BOOL_TRUE;
    241     case 'f':
    242       return T_BOOL_FALSE;
    243     case 'n':
    244       return T_NULL;
    245     case ',':
    246       return T_LIST_SEPARATOR;
    247     case ':':
    248       return T_OBJECT_PAIR_SEPARATOR;
    249     default:
    250       return T_INVALID_TOKEN;
    251   }
    252 }
    253 
    254 void JSONParser::EatWhitespaceAndComments() {
    255   while (pos_ < end_pos_) {
    256     switch (*pos_) {
    257       case '\r':
    258       case '\n':
    259         index_last_line_ = index_;
    260         // Don't increment line_number_ twice for "\r\n".
    261         if (!(*pos_ == '\n' && pos_ > start_pos_ && *(pos_ - 1) == '\r'))
    262           ++line_number_;
    263         // Fall through.
    264       case ' ':
    265       case '\t':
    266         NextChar();
    267         break;
    268       case '/':
    269         if (!EatComment())
    270           return;
    271         break;
    272       default:
    273         return;
    274     }
    275   }
    276 }
    277 
    278 bool JSONParser::EatComment() {
    279   if (*pos_ != '/' || !CanConsume(1))
    280     return false;
    281 
    282   char next_char = *NextChar();
    283   if (next_char == '/') {
    284     // Single line comment, read to newline.
    285     while (CanConsume(1)) {
    286       next_char = *NextChar();
    287       if (next_char == '\n' || next_char == '\r')
    288         return true;
    289     }
    290   } else if (next_char == '*') {
    291     char previous_char = '\0';
    292     // Block comment, read until end marker.
    293     while (CanConsume(1)) {
    294       next_char = *NextChar();
    295       if (previous_char == '*' && next_char == '/') {
    296         // EatWhitespaceAndComments will inspect pos_, which will still be on
    297         // the last / of the comment, so advance once more (which may also be
    298         // end of input).
    299         NextChar();
    300         return true;
    301       }
    302       previous_char = next_char;
    303     }
    304 
    305     // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT.
    306   }
    307 
    308   return false;
    309 }
    310 
    311 std::unique_ptr<Value> JSONParser::ParseNextToken() {
    312   return ParseToken(GetNextToken());
    313 }
    314 
    315 std::unique_ptr<Value> JSONParser::ParseToken(Token token) {
    316   switch (token) {
    317     case T_OBJECT_BEGIN:
    318       return ConsumeDictionary();
    319     case T_ARRAY_BEGIN:
    320       return ConsumeList();
    321     case T_STRING:
    322       return ConsumeString();
    323     case T_NUMBER:
    324       return ConsumeNumber();
    325     case T_BOOL_TRUE:
    326     case T_BOOL_FALSE:
    327     case T_NULL:
    328       return ConsumeLiteral();
    329     default:
    330       ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
    331       return nullptr;
    332   }
    333 }
    334 
    335 std::unique_ptr<Value> JSONParser::ConsumeDictionary() {
    336   if (*pos_ != '{') {
    337     ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
    338     return nullptr;
    339   }
    340 
    341   StackMarker depth_check(&stack_depth_);
    342   if (depth_check.IsTooDeep()) {
    343     ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1);
    344     return nullptr;
    345   }
    346 
    347   std::unique_ptr<DictionaryValue> dict(new DictionaryValue);
    348 
    349   NextChar();
    350   Token token = GetNextToken();
    351   while (token != T_OBJECT_END) {
    352     if (token != T_STRING) {
    353       ReportError(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, 1);
    354       return nullptr;
    355     }
    356 
    357     // First consume the key.
    358     StringBuilder key;
    359     if (!ConsumeStringRaw(&key)) {
    360       return nullptr;
    361     }
    362 
    363     // Read the separator.
    364     NextChar();
    365     token = GetNextToken();
    366     if (token != T_OBJECT_PAIR_SEPARATOR) {
    367       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    368       return nullptr;
    369     }
    370 
    371     // The next token is the value. Ownership transfers to |dict|.
    372     NextChar();
    373     std::unique_ptr<Value> value = ParseNextToken();
    374     if (!value) {
    375       // ReportError from deeper level.
    376       return nullptr;
    377     }
    378 
    379     dict->SetWithoutPathExpansion(key.AsStringPiece(), std::move(value));
    380 
    381     NextChar();
    382     token = GetNextToken();
    383     if (token == T_LIST_SEPARATOR) {
    384       NextChar();
    385       token = GetNextToken();
    386       if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) {
    387         ReportError(JSONReader::JSON_TRAILING_COMMA, 1);
    388         return nullptr;
    389       }
    390     } else if (token != T_OBJECT_END) {
    391       ReportError(JSONReader::JSON_SYNTAX_ERROR, 0);
    392       return nullptr;
    393     }
    394   }
    395 
    396   return std::move(dict);
    397 }
    398 
    399 std::unique_ptr<Value> JSONParser::ConsumeList() {
    400   if (*pos_ != '[') {
    401     ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
    402     return nullptr;
    403   }
    404 
    405   StackMarker depth_check(&stack_depth_);
    406   if (depth_check.IsTooDeep()) {
    407     ReportError(JSONReader::JSON_TOO_MUCH_NESTING, 1);
    408     return nullptr;
    409   }
    410 
    411   std::unique_ptr<ListValue> list(new ListValue);
    412 
    413   NextChar();
    414   Token token = GetNextToken();
    415   while (token != T_ARRAY_END) {
    416     std::unique_ptr<Value> item = ParseToken(token);
    417     if (!item) {
    418       // ReportError from deeper level.
    419       return nullptr;
    420     }
    421 
    422     list->Append(std::move(item));
    423 
    424     NextChar();
    425     token = GetNextToken();
    426     if (token == T_LIST_SEPARATOR) {
    427       NextChar();
    428       token = GetNextToken();
    429       if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) {
    430         ReportError(JSONReader::JSON_TRAILING_COMMA, 1);
    431         return nullptr;
    432       }
    433     } else if (token != T_ARRAY_END) {
    434       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    435       return nullptr;
    436     }
    437   }
    438 
    439   return std::move(list);
    440 }
    441 
    442 std::unique_ptr<Value> JSONParser::ConsumeString() {
    443   StringBuilder string;
    444   if (!ConsumeStringRaw(&string))
    445     return nullptr;
    446 
    447   return base::MakeUnique<Value>(string.DestructiveAsString());
    448 }
    449 
    450 bool JSONParser::ConsumeStringRaw(StringBuilder* out) {
    451   if (*pos_ != '"') {
    452     ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
    453     return false;
    454   }
    455 
    456   // StringBuilder will internally build a StringPiece unless a UTF-16
    457   // conversion occurs, at which point it will perform a copy into a
    458   // std::string.
    459   StringBuilder string(NextChar());
    460 
    461   int length = end_pos_ - start_pos_;
    462   int32_t next_char = 0;
    463 
    464   while (CanConsume(1)) {
    465     int start_index = index_;
    466     pos_ = start_pos_ + index_;  // CBU8_NEXT is postcrement.
    467     CBU8_NEXT(start_pos_, index_, length, next_char);
    468     if (next_char < 0 || !IsValidCharacter(next_char)) {
    469       if ((options_ & JSON_REPLACE_INVALID_CHARACTERS) == 0) {
    470         ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1);
    471         return false;
    472       }
    473       CBU8_NEXT(start_pos_, start_index, length, next_char);
    474       string.Convert();
    475       string.AppendString(kUnicodeReplacementString,
    476                           arraysize(kUnicodeReplacementString) - 1);
    477       continue;
    478     }
    479 
    480     if (next_char == '"') {
    481       --index_;  // Rewind by one because of CBU8_NEXT.
    482       *out = std::move(string);
    483       return true;
    484     }
    485 
    486     // If this character is not an escape sequence...
    487     if (next_char != '\\') {
    488       if (next_char < kExtendedASCIIStart)
    489         string.Append(static_cast<char>(next_char));
    490       else
    491         DecodeUTF8(next_char, &string);
    492     } else {
    493       // And if it is an escape sequence, the input string will be adjusted
    494       // (either by combining the two characters of an encoded escape sequence,
    495       // or with a UTF conversion), so using StringPiece isn't possible -- force
    496       // a conversion.
    497       string.Convert();
    498 
    499       if (!CanConsume(1)) {
    500         ReportError(JSONReader::JSON_INVALID_ESCAPE, 0);
    501         return false;
    502       }
    503 
    504       switch (*NextChar()) {
    505         // Allowed esape sequences:
    506         case 'x': {  // UTF-8 sequence.
    507           // UTF-8 \x escape sequences are not allowed in the spec, but they
    508           // are supported here for backwards-compatiblity with the old parser.
    509           if (!CanConsume(2)) {
    510             ReportError(JSONReader::JSON_INVALID_ESCAPE, 1);
    511             return false;
    512           }
    513 
    514           int hex_digit = 0;
    515           if (!HexStringToInt(StringPiece(NextChar(), 2), &hex_digit) ||
    516               !IsValidCharacter(hex_digit)) {
    517             ReportError(JSONReader::JSON_INVALID_ESCAPE, -1);
    518             return false;
    519           }
    520           NextChar();
    521 
    522           if (hex_digit < kExtendedASCIIStart)
    523             string.Append(static_cast<char>(hex_digit));
    524           else
    525             DecodeUTF8(hex_digit, &string);
    526           break;
    527         }
    528         case 'u': {  // UTF-16 sequence.
    529           // UTF units are of the form \uXXXX.
    530           if (!CanConsume(5)) {  // 5 being 'u' and four HEX digits.
    531             ReportError(JSONReader::JSON_INVALID_ESCAPE, 0);
    532             return false;
    533           }
    534 
    535           // Skip the 'u'.
    536           NextChar();
    537 
    538           std::string utf8_units;
    539           if (!DecodeUTF16(&utf8_units)) {
    540             ReportError(JSONReader::JSON_INVALID_ESCAPE, -1);
    541             return false;
    542           }
    543 
    544           string.AppendString(utf8_units.data(), utf8_units.length());
    545           break;
    546         }
    547         case '"':
    548           string.Append('"');
    549           break;
    550         case '\\':
    551           string.Append('\\');
    552           break;
    553         case '/':
    554           string.Append('/');
    555           break;
    556         case 'b':
    557           string.Append('\b');
    558           break;
    559         case 'f':
    560           string.Append('\f');
    561           break;
    562         case 'n':
    563           string.Append('\n');
    564           break;
    565         case 'r':
    566           string.Append('\r');
    567           break;
    568         case 't':
    569           string.Append('\t');
    570           break;
    571         case 'v':  // Not listed as valid escape sequence in the RFC.
    572           string.Append('\v');
    573           break;
    574         // All other escape squences are illegal.
    575         default:
    576           ReportError(JSONReader::JSON_INVALID_ESCAPE, 0);
    577           return false;
    578       }
    579     }
    580   }
    581 
    582   ReportError(JSONReader::JSON_SYNTAX_ERROR, 0);
    583   return false;
    584 }
    585 
    586 // Entry is at the first X in \uXXXX.
    587 bool JSONParser::DecodeUTF16(std::string* dest_string) {
    588   if (!CanConsume(4))
    589     return false;
    590 
    591   // This is a 32-bit field because the shift operations in the
    592   // conversion process below cause MSVC to error about "data loss."
    593   // This only stores UTF-16 code units, though.
    594   // Consume the UTF-16 code unit, which may be a high surrogate.
    595   int code_unit16_high = 0;
    596   if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_high))
    597     return false;
    598 
    599   // Only add 3, not 4, because at the end of this iteration, the parser has
    600   // finished working with the last digit of the UTF sequence, meaning that
    601   // the next iteration will advance to the next byte.
    602   NextNChars(3);
    603 
    604   // Used to convert the UTF-16 code units to a code point and then to a UTF-8
    605   // code unit sequence.
    606   char code_unit8[8] = { 0 };
    607   size_t offset = 0;
    608 
    609   // If this is a high surrogate, consume the next code unit to get the
    610   // low surrogate.
    611   if (CBU16_IS_SURROGATE(code_unit16_high)) {
    612     // Make sure this is the high surrogate. If not, it's an encoding
    613     // error.
    614     if (!CBU16_IS_SURROGATE_LEAD(code_unit16_high))
    615       return false;
    616 
    617     // Make sure that the token has more characters to consume the
    618     // lower surrogate.
    619     if (!CanConsume(6))  // 6 being '\' 'u' and four HEX digits.
    620       return false;
    621     if (*NextChar() != '\\' || *NextChar() != 'u')
    622       return false;
    623 
    624     NextChar();  // Read past 'u'.
    625     int code_unit16_low = 0;
    626     if (!HexStringToInt(StringPiece(pos_, 4), &code_unit16_low))
    627       return false;
    628 
    629     NextNChars(3);
    630 
    631     if (!CBU16_IS_TRAIL(code_unit16_low)) {
    632       return false;
    633     }
    634 
    635     uint32_t code_point =
    636         CBU16_GET_SUPPLEMENTARY(code_unit16_high, code_unit16_low);
    637     if (!IsValidCharacter(code_point))
    638       return false;
    639 
    640     offset = 0;
    641     CBU8_APPEND_UNSAFE(code_unit8, offset, code_point);
    642   } else {
    643     // Not a surrogate.
    644     DCHECK(CBU16_IS_SINGLE(code_unit16_high));
    645     if (!IsValidCharacter(code_unit16_high))
    646       return false;
    647 
    648     CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high);
    649   }
    650 
    651   dest_string->append(code_unit8);
    652   return true;
    653 }
    654 
    655 void JSONParser::DecodeUTF8(const int32_t& point, StringBuilder* dest) {
    656   DCHECK(IsValidCharacter(point));
    657 
    658   // Anything outside of the basic ASCII plane will need to be decoded from
    659   // int32_t to a multi-byte sequence.
    660   if (point < kExtendedASCIIStart) {
    661     dest->Append(static_cast<char>(point));
    662   } else {
    663     char utf8_units[4] = { 0 };
    664     int offset = 0;
    665     CBU8_APPEND_UNSAFE(utf8_units, offset, point);
    666     dest->Convert();
    667     // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be
    668     // zero terminated at this point.  |offset| contains the correct length.
    669     dest->AppendString(utf8_units, offset);
    670   }
    671 }
    672 
    673 std::unique_ptr<Value> JSONParser::ConsumeNumber() {
    674   const char* num_start = pos_;
    675   const int start_index = index_;
    676   int end_index = start_index;
    677 
    678   if (*pos_ == '-')
    679     NextChar();
    680 
    681   if (!ReadInt(false)) {
    682     ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    683     return nullptr;
    684   }
    685   end_index = index_;
    686 
    687   // The optional fraction part.
    688   if (CanConsume(1) && *pos_ == '.') {
    689     NextChar();
    690     if (!ReadInt(true)) {
    691       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    692       return nullptr;
    693     }
    694     end_index = index_;
    695   }
    696 
    697   // Optional exponent part.
    698   if (CanConsume(1) && (*pos_ == 'e' || *pos_ == 'E')) {
    699     NextChar();
    700     if (!CanConsume(1)) {
    701       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    702       return nullptr;
    703     }
    704     if (*pos_ == '-' || *pos_ == '+') {
    705       NextChar();
    706     }
    707     if (!ReadInt(true)) {
    708       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    709       return nullptr;
    710     }
    711     end_index = index_;
    712   }
    713 
    714   // ReadInt is greedy because numbers have no easily detectable sentinel,
    715   // so save off where the parser should be on exit (see Consume invariant at
    716   // the top of the header), then make sure the next token is one which is
    717   // valid.
    718   const char* exit_pos = pos_ - 1;
    719   int exit_index = index_ - 1;
    720 
    721   switch (GetNextToken()) {
    722     case T_OBJECT_END:
    723     case T_ARRAY_END:
    724     case T_LIST_SEPARATOR:
    725     case T_END_OF_INPUT:
    726       break;
    727     default:
    728       ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    729       return nullptr;
    730   }
    731 
    732   pos_ = exit_pos;
    733   index_ = exit_index;
    734 
    735   StringPiece num_string(num_start, end_index - start_index);
    736 
    737   int num_int;
    738   if (StringToInt(num_string, &num_int))
    739     return base::MakeUnique<Value>(num_int);
    740 
    741   double num_double;
    742   if (StringToDouble(num_string.as_string(), &num_double) &&
    743       std::isfinite(num_double)) {
    744     return base::MakeUnique<Value>(num_double);
    745   }
    746 
    747   return nullptr;
    748 }
    749 
    750 bool JSONParser::ReadInt(bool allow_leading_zeros) {
    751   size_t len = 0;
    752   char first = 0;
    753 
    754   while (CanConsume(1)) {
    755     if (!IsAsciiDigit(*pos_))
    756       break;
    757 
    758     if (len == 0)
    759       first = *pos_;
    760 
    761     ++len;
    762     NextChar();
    763   }
    764 
    765   if (len == 0)
    766     return false;
    767 
    768   if (!allow_leading_zeros && len > 1 && first == '0')
    769     return false;
    770 
    771   return true;
    772 }
    773 
    774 std::unique_ptr<Value> JSONParser::ConsumeLiteral() {
    775   switch (*pos_) {
    776     case 't': {
    777       const char kTrueLiteral[] = "true";
    778       const int kTrueLen = static_cast<int>(strlen(kTrueLiteral));
    779       if (!CanConsume(kTrueLen - 1) ||
    780           !StringsAreEqual(pos_, kTrueLiteral, kTrueLen)) {
    781         ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    782         return nullptr;
    783       }
    784       NextNChars(kTrueLen - 1);
    785       return base::MakeUnique<Value>(true);
    786     }
    787     case 'f': {
    788       const char kFalseLiteral[] = "false";
    789       const int kFalseLen = static_cast<int>(strlen(kFalseLiteral));
    790       if (!CanConsume(kFalseLen - 1) ||
    791           !StringsAreEqual(pos_, kFalseLiteral, kFalseLen)) {
    792         ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    793         return nullptr;
    794       }
    795       NextNChars(kFalseLen - 1);
    796       return base::MakeUnique<Value>(false);
    797     }
    798     case 'n': {
    799       const char kNullLiteral[] = "null";
    800       const int kNullLen = static_cast<int>(strlen(kNullLiteral));
    801       if (!CanConsume(kNullLen - 1) ||
    802           !StringsAreEqual(pos_, kNullLiteral, kNullLen)) {
    803         ReportError(JSONReader::JSON_SYNTAX_ERROR, 1);
    804         return nullptr;
    805       }
    806       NextNChars(kNullLen - 1);
    807       return Value::CreateNullValue();
    808     }
    809     default:
    810       ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1);
    811       return nullptr;
    812   }
    813 }
    814 
    815 // static
    816 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) {
    817   return strncmp(one, two, len) == 0;
    818 }
    819 
    820 void JSONParser::ReportError(JSONReader::JsonParseError code,
    821                              int column_adjust) {
    822   error_code_ = code;
    823   error_line_ = line_number_;
    824   error_column_ = index_ - index_last_line_ + column_adjust;
    825 }
    826 
    827 // static
    828 std::string JSONParser::FormatErrorMessage(int line, int column,
    829                                            const std::string& description) {
    830   if (line || column) {
    831     return StringPrintf("Line: %i, column: %i, %s",
    832         line, column, description.c_str());
    833   }
    834   return description;
    835 }
    836 
    837 }  // namespace internal
    838 }  // namespace base
    839