• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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