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