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
22namespace base {
23namespace internal {
24
25namespace {
26
27// Chosen to support 99.9% of documents found in the wild late 2016.
28// http://crbug.com/673263
29const int kStackMaxDepth = 200;
30
31const int32_t kExtendedASCIIStart = 0x80;
32
33// Simple class that checks for maximum recursion/"stack overflow."
34class 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.
57const char kUnicodeReplacementString[] = "\xEF\xBF\xBD";
58
59JSONParser::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
73JSONParser::~JSONParser() {
74}
75
76std::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
114JSONReader::JsonParseError JSONParser::error_code() const {
115  return error_code_;
116}
117
118std::string JSONParser::GetErrorMessage() const {
119  return FormatErrorMessage(error_line_, error_column_,
120      JSONReader::ErrorCodeToString(error_code_));
121}
122
123int JSONParser::error_line() const {
124  return error_line_;
125}
126
127int JSONParser::error_column() const {
128  return error_column_;
129}
130
131// StringBuilder ///////////////////////////////////////////////////////////////
132
133JSONParser::StringBuilder::StringBuilder() : StringBuilder(nullptr) {}
134
135JSONParser::StringBuilder::StringBuilder(const char* pos)
136    : pos_(pos), length_(0), has_string_(false) {}
137
138JSONParser::StringBuilder::~StringBuilder() {
139  if (has_string_)
140    string_.Destroy();
141}
142
143void 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
151void 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
161void JSONParser::StringBuilder::AppendString(const char* str, size_t len) {
162  DCHECK(has_string_);
163  string_->append(str, len);
164}
165
166void JSONParser::StringBuilder::Convert() {
167  if (has_string_)
168    return;
169
170  has_string_ = true;
171  string_.Init(pos_, length_);
172}
173
174StringPiece JSONParser::StringBuilder::AsStringPiece() {
175  if (has_string_)
176    return StringPiece(*string_);
177  return StringPiece(pos_, length_);
178}
179
180const std::string& JSONParser::StringBuilder::AsString() {
181  if (!has_string_)
182    Convert();
183  return *string_;
184}
185
186std::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
194inline bool JSONParser::CanConsume(int length) {
195  return pos_ + length <= end_pos_;
196}
197
198const char* JSONParser::NextChar() {
199  DCHECK(CanConsume(1));
200  ++index_;
201  ++pos_;
202  return pos_;
203}
204
205void JSONParser::NextNChars(int n) {
206  DCHECK(CanConsume(n));
207  index_ += n;
208  pos_ += n;
209}
210
211JSONParser::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
254void 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
278bool 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
311std::unique_ptr<Value> JSONParser::ParseNextToken() {
312  return ParseToken(GetNextToken());
313}
314
315std::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
335std::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
399std::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
442std::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
450bool 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.
587bool 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
655void 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
673std::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
750bool 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
774std::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
816bool JSONParser::StringsAreEqual(const char* one, const char* two, size_t len) {
817  return strncmp(one, two, len) == 0;
818}
819
820void 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
828std::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