| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/json/json_parser.h" | 5 #include "base/json/json_parser.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 default: | 272 default: |
| 273 return; | 273 return; |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 } | 276 } |
| 277 | 277 |
| 278 bool JSONParser::EatComment() { | 278 bool JSONParser::EatComment() { |
| 279 if (*pos_ != '/' || !CanConsume(1)) | 279 if (*pos_ != '/' || !CanConsume(1)) |
| 280 return false; | 280 return false; |
| 281 | 281 |
| 282 char next_char = *NextChar(); | 282 NextChar(); |
| 283 if (next_char == '/') { | 283 |
| 284 if (!CanConsume(1)) |
| 285 return false; |
| 286 |
| 287 if (*pos_ == '/') { |
| 284 // Single line comment, read to newline. | 288 // Single line comment, read to newline. |
| 285 while (CanConsume(1)) { | 289 while (CanConsume(1)) { |
| 286 next_char = *NextChar(); | 290 if (*pos_ == '\n' || *pos_ == '\r') |
| 287 if (next_char == '\n' || next_char == '\r') | |
| 288 return true; | 291 return true; |
| 292 NextChar(); |
| 289 } | 293 } |
| 290 } else if (next_char == '*') { | 294 } else if (*pos_ == '*') { |
| 291 char previous_char = '\0'; | 295 char previous_char = '\0'; |
| 292 // Block comment, read until end marker. | 296 // Block comment, read until end marker. |
| 293 while (CanConsume(1)) { | 297 while (CanConsume(1)) { |
| 294 next_char = *NextChar(); | 298 if (previous_char == '*' && *pos_ == '/') { |
| 295 if (previous_char == '*' && next_char == '/') { | |
| 296 // EatWhitespaceAndComments will inspect pos_, which will still be on | 299 // EatWhitespaceAndComments will inspect pos_, which will still be on |
| 297 // the last / of the comment, so advance once more (which may also be | 300 // the last / of the comment, so advance once more (which may also be |
| 298 // end of input). | 301 // end of input). |
| 299 NextChar(); | 302 NextChar(); |
| 300 return true; | 303 return true; |
| 301 } | 304 } |
| 302 previous_char = next_char; | 305 previous_char = *pos_; |
| 306 NextChar(); |
| 303 } | 307 } |
| 304 | 308 |
| 305 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. | 309 // If the comment is unterminated, GetNextToken will report T_END_OF_INPUT. |
| 306 } | 310 } |
| 307 | 311 |
| 308 return false; | 312 return false; |
| 309 } | 313 } |
| 310 | 314 |
| 311 std::unique_ptr<Value> JSONParser::ParseNextToken() { | 315 std::unique_ptr<Value> JSONParser::ParseNextToken() { |
| 312 return ParseToken(GetNextToken()); | 316 return ParseToken(GetNextToken()); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 | 451 |
| 448 return base::MakeUnique<Value>(string.DestructiveAsString()); | 452 return base::MakeUnique<Value>(string.DestructiveAsString()); |
| 449 } | 453 } |
| 450 | 454 |
| 451 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { | 455 bool JSONParser::ConsumeStringRaw(StringBuilder* out) { |
| 452 if (*pos_ != '"') { | 456 if (*pos_ != '"') { |
| 453 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); | 457 ReportError(JSONReader::JSON_UNEXPECTED_TOKEN, 1); |
| 454 return false; | 458 return false; |
| 455 } | 459 } |
| 456 | 460 |
| 461 // Strings are at minimum two characters: the surrounding double quotes. |
| 462 if (!CanConsume(2)) { |
| 463 ReportError(JSONReader::JSON_SYNTAX_ERROR, 1); |
| 464 return false; |
| 465 } |
| 466 |
| 457 // StringBuilder will internally build a StringPiece unless a UTF-16 | 467 // StringBuilder will internally build a StringPiece unless a UTF-16 |
| 458 // conversion occurs, at which point it will perform a copy into a | 468 // conversion occurs, at which point it will perform a copy into a |
| 459 // std::string. | 469 // std::string. |
| 460 StringBuilder string(NextChar()); | 470 StringBuilder string(NextChar()); |
| 461 | 471 |
| 472 // Handle the empty string case early. |
| 473 if (*pos_ == '"') { |
| 474 *out = std::move(string); |
| 475 return true; |
| 476 } |
| 477 |
| 462 int length = end_pos_ - start_pos_; | 478 int length = end_pos_ - start_pos_; |
| 463 int32_t next_char = 0; | 479 int32_t next_char = 0; |
| 464 | 480 |
| 465 while (CanConsume(1)) { | 481 // There must always be at least two characters left in the stream: the next |
| 482 // string character and the terminating closing quote. |
| 483 while (CanConsume(2)) { |
| 466 int start_index = index_; | 484 int start_index = index_; |
| 467 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. | 485 pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement. |
| 468 CBU8_NEXT(start_pos_, index_, length, next_char); | 486 CBU8_NEXT(start_pos_, index_, length, next_char); |
| 469 if (next_char < 0 || !IsValidCharacter(next_char)) { | 487 if (next_char < 0 || !IsValidCharacter(next_char)) { |
| 470 if ((options_ & JSON_REPLACE_INVALID_CHARACTERS) == 0) { | 488 if ((options_ & JSON_REPLACE_INVALID_CHARACTERS) == 0) { |
| 471 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); | 489 ReportError(JSONReader::JSON_UNSUPPORTED_ENCODING, 1); |
| 472 return false; | 490 return false; |
| 473 } | 491 } |
| 474 CBU8_NEXT(start_pos_, start_index, length, next_char); | 492 CBU8_NEXT(start_pos_, start_index, length, next_char); |
| 475 string.Convert(); | 493 string.Convert(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 495 // (either by combining the two characters of an encoded escape sequence, | 513 // (either by combining the two characters of an encoded escape sequence, |
| 496 // or with a UTF conversion), so using StringPiece isn't possible -- force | 514 // or with a UTF conversion), so using StringPiece isn't possible -- force |
| 497 // a conversion. | 515 // a conversion. |
| 498 string.Convert(); | 516 string.Convert(); |
| 499 | 517 |
| 500 if (!CanConsume(1)) { | 518 if (!CanConsume(1)) { |
| 501 ReportError(JSONReader::JSON_INVALID_ESCAPE, 0); | 519 ReportError(JSONReader::JSON_INVALID_ESCAPE, 0); |
| 502 return false; | 520 return false; |
| 503 } | 521 } |
| 504 | 522 |
| 505 switch (*NextChar()) { | 523 NextChar(); |
| 524 if (!CanConsume(1)) { |
| 525 ReportError(JSONReader::JSON_INVALID_ESCAPE, 0); |
| 526 return false; |
| 527 } |
| 528 |
| 529 switch (*pos_) { |
| 506 // Allowed esape sequences: | 530 // Allowed esape sequences: |
| 507 case 'x': { // UTF-8 sequence. | 531 case 'x': { // UTF-8 sequence. |
| 508 // UTF-8 \x escape sequences are not allowed in the spec, but they | 532 // UTF-8 \x escape sequences are not allowed in the spec, but they |
| 509 // are supported here for backwards-compatiblity with the old parser. | 533 // are supported here for backwards-compatiblity with the old parser. |
| 510 if (!CanConsume(2)) { | 534 if (!CanConsume(2)) { |
| 511 ReportError(JSONReader::JSON_INVALID_ESCAPE, 1); | 535 ReportError(JSONReader::JSON_INVALID_ESCAPE, 1); |
| 512 return false; | 536 return false; |
| 513 } | 537 } |
| 514 | 538 |
| 515 int hex_digit = 0; | 539 int hex_digit = 0; |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 const std::string& description) { | 854 const std::string& description) { |
| 831 if (line || column) { | 855 if (line || column) { |
| 832 return StringPrintf("Line: %i, column: %i, %s", | 856 return StringPrintf("Line: %i, column: %i, %s", |
| 833 line, column, description.c_str()); | 857 line, column, description.c_str()); |
| 834 } | 858 } |
| 835 return description; | 859 return description; |
| 836 } | 860 } |
| 837 | 861 |
| 838 } // namespace internal | 862 } // namespace internal |
| 839 } // namespace base | 863 } // namespace base |
| OLD | NEW |