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:
StackMarker(int * depth)36 explicit StackMarker(int* depth) : depth_(depth) {
37 ++(*depth_);
38 DCHECK_LE(*depth_, kStackMaxDepth);
39 }
~StackMarker()40 ~StackMarker() {
41 --(*depth_);
42 }
43
IsTooDeep() const44 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
JSONParser(int options)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
~JSONParser()73 JSONParser::~JSONParser() {
74 }
75
Parse(StringPiece input)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
error_code() const114 JSONReader::JsonParseError JSONParser::error_code() const {
115 return error_code_;
116 }
117
GetErrorMessage() const118 std::string JSONParser::GetErrorMessage() const {
119 return FormatErrorMessage(error_line_, error_column_,
120 JSONReader::ErrorCodeToString(error_code_));
121 }
122
error_line() const123 int JSONParser::error_line() const {
124 return error_line_;
125 }
126
error_column() const127 int JSONParser::error_column() const {
128 return error_column_;
129 }
130
131 // StringBuilder ///////////////////////////////////////////////////////////////
132
StringBuilder()133 JSONParser::StringBuilder::StringBuilder() : StringBuilder(nullptr) {}
134
StringBuilder(const char * pos)135 JSONParser::StringBuilder::StringBuilder(const char* pos)
136 : pos_(pos), length_(0), has_string_(false) {}
137
~StringBuilder()138 JSONParser::StringBuilder::~StringBuilder() {
139 if (has_string_)
140 string_.Destroy();
141 }
142
operator =(StringBuilder && other)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
Append(const char & c)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
AppendString(const char * str,size_t len)161 void JSONParser::StringBuilder::AppendString(const char* str, size_t len) {
162 DCHECK(has_string_);
163 string_->append(str, len);
164 }
165
Convert()166 void JSONParser::StringBuilder::Convert() {
167 if (has_string_)
168 return;
169
170 has_string_ = true;
171 string_.Init(pos_, length_);
172 }
173
AsStringPiece()174 StringPiece JSONParser::StringBuilder::AsStringPiece() {
175 if (has_string_)
176 return StringPiece(*string_);
177 return StringPiece(pos_, length_);
178 }
179
AsString()180 const std::string& JSONParser::StringBuilder::AsString() {
181 if (!has_string_)
182 Convert();
183 return *string_;
184 }
185
DestructiveAsString()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
CanConsume(int length)194 inline bool JSONParser::CanConsume(int length) {
195 return pos_ + length <= end_pos_;
196 }
197
NextChar()198 const char* JSONParser::NextChar() {
199 DCHECK(CanConsume(1));
200 ++index_;
201 ++pos_;
202 return pos_;
203 }
204
NextNChars(int n)205 void JSONParser::NextNChars(int n) {
206 DCHECK(CanConsume(n));
207 index_ += n;
208 pos_ += n;
209 }
210
GetNextToken()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
EatWhitespaceAndComments()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
EatComment()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
ParseNextToken()311 std::unique_ptr<Value> JSONParser::ParseNextToken() {
312 return ParseToken(GetNextToken());
313 }
314
ParseToken(Token token)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
ConsumeDictionary()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
ConsumeList()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
ConsumeString()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
ConsumeStringRaw(StringBuilder * out)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.
DecodeUTF16(std::string * dest_string)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
DecodeUTF8(const int32_t & point,StringBuilder * dest)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
ConsumeNumber()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
ReadInt(bool allow_leading_zeros)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
ConsumeLiteral()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
StringsAreEqual(const char * one,const char * two,size_t len)816 bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) {
817 return strncmp(one, two, len) == 0;
818 }
819
ReportError(JSONReader::JsonParseError code,int column_adjust)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
FormatErrorMessage(int line,int column,const std::string & description)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