Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 27 matching lines...) Expand all
38 #include <memory> 38 #include <memory>
39 #ifndef _SHARED_PTR_H 39 #ifndef _SHARED_PTR_H
40 #include <google/protobuf/stubs/shared_ptr.h> 40 #include <google/protobuf/stubs/shared_ptr.h>
41 #endif 41 #endif
42 42
43 #include <google/protobuf/stubs/logging.h> 43 #include <google/protobuf/stubs/logging.h>
44 #include <google/protobuf/stubs/common.h> 44 #include <google/protobuf/stubs/common.h>
45 #include <google/protobuf/util/internal/object_writer.h> 45 #include <google/protobuf/util/internal/object_writer.h>
46 #include <google/protobuf/util/internal/json_escaping.h> 46 #include <google/protobuf/util/internal/json_escaping.h>
47 #include <google/protobuf/stubs/strutil.h> 47 #include <google/protobuf/stubs/strutil.h>
48 #include <google/protobuf/stubs/mathlimits.h>
49
48 50
49 namespace google { 51 namespace google {
50 namespace protobuf { 52 namespace protobuf {
51 namespace util { 53 namespace util {
52 54
53 // Allow these symbols to be referenced as util::Status, util::error::* in 55 // Allow these symbols to be referenced as util::Status, util::error::* in
54 // this file. 56 // this file.
55 using util::Status; 57 using util::Status;
56 namespace error { 58 namespace error {
57 using util::error::INTERNAL; 59 using util::error::INTERNAL;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 leftover_(), 102 leftover_(),
101 json_(), 103 json_(),
102 p_(), 104 p_(),
103 key_(), 105 key_(),
104 key_storage_(), 106 key_storage_(),
105 finishing_(false), 107 finishing_(false),
106 parsed_(), 108 parsed_(),
107 parsed_storage_(), 109 parsed_storage_(),
108 string_open_(0), 110 string_open_(0),
109 chunk_storage_(), 111 chunk_storage_(),
110 coerce_to_utf8_(false) { 112 coerce_to_utf8_(false),
113 allow_empty_null_(false),
114 loose_float_number_conversion_(false) {
111 // Initialize the stack with a single value to be parsed. 115 // Initialize the stack with a single value to be parsed.
112 stack_.push(VALUE); 116 stack_.push(VALUE);
113 } 117 }
114 118
115 JsonStreamParser::~JsonStreamParser() {} 119 JsonStreamParser::~JsonStreamParser() {}
116 120
117 121
118 util::Status JsonStreamParser::Parse(StringPiece json) { 122 util::Status JsonStreamParser::Parse(StringPiece json) {
119 StringPiece chunk = json; 123 StringPiece chunk = json;
120 // If we have leftovers from a previous chunk, append the new chunk to it 124 // If we have leftovers from a previous chunk, append the new chunk to it
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return ParseNumber(); 274 return ParseNumber();
271 case BEGIN_TRUE: 275 case BEGIN_TRUE:
272 return ParseTrue(); 276 return ParseTrue();
273 case BEGIN_FALSE: 277 case BEGIN_FALSE:
274 return ParseFalse(); 278 return ParseFalse();
275 case BEGIN_NULL: 279 case BEGIN_NULL:
276 return ParseNull(); 280 return ParseNull();
277 case UNKNOWN: 281 case UNKNOWN:
278 return ReportUnknown("Expected a value."); 282 return ReportUnknown("Expected a value.");
279 default: { 283 default: {
284 if (allow_empty_null_ && IsEmptyNullAllowed(type)) {
285 return ParseEmptyNull();
286 }
287
280 // Special case for having been cut off while parsing, wait for more data. 288 // Special case for having been cut off while parsing, wait for more data.
281 // This handles things like 'fals' being at the end of the string, we 289 // This handles things like 'fals' being at the end of the string, we
282 // don't know if the next char would be e, completing it, or something 290 // don't know if the next char would be e, completing it, or something
283 // else, making it invalid. 291 // else, making it invalid.
284 if (!finishing_ && p_.length() < false_len) { 292 if (!finishing_ && p_.length() < false_len) {
285 return util::Status::CANCELLED; 293 return util::Status::CANCELLED;
286 } 294 }
287 return ReportFailure("Unexpected token."); 295 return ReportFailure("Unexpected token.");
288 } 296 }
289 } 297 }
290 } 298 }
291 299
292 util::Status JsonStreamParser::ParseString() { 300 util::Status JsonStreamParser::ParseString() {
293 util::Status result = ParseStringHelper(); 301 util::Status result = ParseStringHelper();
294 if (result.ok()) { 302 if (result.ok()) {
295 ow_->RenderString(key_, parsed_); 303 ow_->RenderString(key_, parsed_);
296 key_.clear(); 304 key_ = StringPiece();
297 parsed_.clear(); 305 parsed_ = StringPiece();
298 parsed_storage_.clear(); 306 parsed_storage_.clear();
299 } 307 }
300 return result; 308 return result;
301 } 309 }
302 310
303 util::Status JsonStreamParser::ParseStringHelper() { 311 util::Status JsonStreamParser::ParseStringHelper() {
304 // If we haven't seen the start quote, grab it and remember it for later. 312 // If we haven't seen the start quote, grab it and remember it for later.
305 if (string_open_ == 0) { 313 if (string_open_ == 0) {
306 string_open_ = *p_.data(); 314 string_open_ = *p_.data();
307 GOOGLE_DCHECK(string_open_ == '\"' || string_open_ == '\''); 315 GOOGLE_DCHECK(string_open_ == '\"' || string_open_ == '\'');
308 Advance(); 316 Advance();
309 } 317 }
310 // Track where we last copied data from so we can minimize copying. 318 // Track where we last copied data from so we can minimize copying.
311 const char* last = p_.data(); 319 const char* last = p_.data();
312 while (!p_.empty()) { 320 while (!p_.empty()) {
313 const char* data = p_.data(); 321 const char* data = p_.data();
314 if (*data == '\\') { 322 if (*data == '\\') {
315 // We're about to handle an escape, copy all bytes from last to data. 323 // We're about to handle an escape, copy all bytes from last to data.
316 if (last < data) { 324 if (last < data) {
317 parsed_storage_.append(last, data - last); 325 parsed_storage_.append(last, data - last);
318 last = data;
319 } 326 }
320 // If we ran out of string after the \, cancel or report an error 327 // If we ran out of string after the \, cancel or report an error
321 // depending on if we expect more data later. 328 // depending on if we expect more data later.
322 if (p_.length() == 1) { 329 if (p_.length() == 1) {
323 if (!finishing_) { 330 if (!finishing_) {
324 return util::Status::CANCELLED; 331 return util::Status::CANCELLED;
325 } 332 }
326 return ReportFailure("Closing quote expected in string."); 333 return ReportFailure("Closing quote expected in string.");
327 } 334 }
328 // Parse a unicode escape if we found \u in the string. 335 // Parse a unicode escape if we found \u in the string.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 continue; 371 continue;
365 } 372 }
366 // If we found the closing quote note it, advance past it, and return. 373 // If we found the closing quote note it, advance past it, and return.
367 if (*data == string_open_) { 374 if (*data == string_open_) {
368 // If we didn't copy anything, reuse the input buffer. 375 // If we didn't copy anything, reuse the input buffer.
369 if (parsed_storage_.empty()) { 376 if (parsed_storage_.empty()) {
370 parsed_ = StringPiece(last, data - last); 377 parsed_ = StringPiece(last, data - last);
371 } else { 378 } else {
372 if (last < data) { 379 if (last < data) {
373 parsed_storage_.append(last, data - last); 380 parsed_storage_.append(last, data - last);
374 last = data;
375 } 381 }
376 parsed_ = StringPiece(parsed_storage_); 382 parsed_ = StringPiece(parsed_storage_);
377 } 383 }
378 // Clear the quote char so next time we try to parse a string we'll 384 // Clear the quote char so next time we try to parse a string we'll
379 // start fresh. 385 // start fresh.
380 string_open_ = 0; 386 string_open_ = 0;
381 Advance(); 387 Advance();
382 return util::Status::OK; 388 return util::Status::OK;
383 } 389 }
384 // Normal character, just advance past it. 390 // Normal character, just advance past it.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 return util::Status::OK; 470 return util::Status::OK;
465 } 471 }
466 472
467 util::Status JsonStreamParser::ParseNumber() { 473 util::Status JsonStreamParser::ParseNumber() {
468 NumberResult number; 474 NumberResult number;
469 util::Status result = ParseNumberHelper(&number); 475 util::Status result = ParseNumberHelper(&number);
470 if (result.ok()) { 476 if (result.ok()) {
471 switch (number.type) { 477 switch (number.type) {
472 case NumberResult::DOUBLE: 478 case NumberResult::DOUBLE:
473 ow_->RenderDouble(key_, number.double_val); 479 ow_->RenderDouble(key_, number.double_val);
474 key_.clear(); 480 key_ = StringPiece();
475 break; 481 break;
476 482
477 case NumberResult::INT: 483 case NumberResult::INT:
478 ow_->RenderInt64(key_, number.int_val); 484 ow_->RenderInt64(key_, number.int_val);
479 key_.clear(); 485 key_ = StringPiece();
480 break; 486 break;
481 487
482 case NumberResult::UINT: 488 case NumberResult::UINT:
483 ow_->RenderUint64(key_, number.uint_val); 489 ow_->RenderUint64(key_, number.uint_val);
484 key_.clear(); 490 key_ = StringPiece();
485 break; 491 break;
486 492
487 default: 493 default:
488 return ReportFailure("Unable to parse number."); 494 return ReportFailure("Unable to parse number.");
489 } 495 }
490 } 496 }
491 return result; 497 return result;
492 } 498 }
493 499
494 util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { 500 util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
(...skipping 27 matching lines...) Expand all
522 } 528 }
523 529
524 // Create a string containing just the number, so we can use safe_strtoX 530 // Create a string containing just the number, so we can use safe_strtoX
525 string number = p_.substr(0, index).ToString(); 531 string number = p_.substr(0, index).ToString();
526 532
527 // Floating point number, parse as a double. 533 // Floating point number, parse as a double.
528 if (floating) { 534 if (floating) {
529 if (!safe_strtod(number, &result->double_val)) { 535 if (!safe_strtod(number, &result->double_val)) {
530 return ReportFailure("Unable to parse number."); 536 return ReportFailure("Unable to parse number.");
531 } 537 }
538 if (!loose_float_number_conversion_ &&
539 !MathLimits<double>::IsFinite(result->double_val)) {
540 return ReportFailure("Number exceeds the range of double.");
541 }
532 result->type = NumberResult::DOUBLE; 542 result->type = NumberResult::DOUBLE;
533 p_.remove_prefix(index); 543 p_.remove_prefix(index);
534 return util::Status::OK; 544 return util::Status::OK;
535 } 545 }
536 546
537 // Positive non-floating point number, parse as a uint64. 547 // Positive non-floating point number, parse as a uint64.
538 if (!negative) { 548 if (!negative) {
539 // Octal/Hex numbers are not valid JSON values. 549 // Octal/Hex numbers are not valid JSON values.
540 if (number.length() >= 2 && number[0] == '0') { 550 if (number.length() >= 2 && number[0] == '0') {
541 return ReportFailure("Octal/hex numbers are not valid JSON values."); 551 return ReportFailure("Octal/hex numbers are not valid JSON values.");
(...skipping 16 matching lines...) Expand all
558 } 568 }
559 result->type = NumberResult::INT; 569 result->type = NumberResult::INT;
560 p_.remove_prefix(index); 570 p_.remove_prefix(index);
561 return util::Status::OK; 571 return util::Status::OK;
562 } 572 }
563 573
564 util::Status JsonStreamParser::HandleBeginObject() { 574 util::Status JsonStreamParser::HandleBeginObject() {
565 GOOGLE_DCHECK_EQ('{', *p_.data()); 575 GOOGLE_DCHECK_EQ('{', *p_.data());
566 Advance(); 576 Advance();
567 ow_->StartObject(key_); 577 ow_->StartObject(key_);
568 key_.clear(); 578 key_ = StringPiece();
569 stack_.push(ENTRY); 579 stack_.push(ENTRY);
570 return util::Status::OK; 580 return util::Status::OK;
571 } 581 }
572 582
573 util::Status JsonStreamParser::ParseObjectMid(TokenType type) { 583 util::Status JsonStreamParser::ParseObjectMid(TokenType type) {
574 if (type == UNKNOWN) { 584 if (type == UNKNOWN) {
575 return ReportUnknown("Expected , or } after key:value pair."); 585 return ReportUnknown("Expected , or } after key:value pair.");
576 } 586 }
577 587
578 // Object is complete, advance past the comma and render the EndObject. 588 // Object is complete, advance past the comma and render the EndObject.
(...skipping 29 matching lines...) Expand all
608 // Key is a string (standard JSON), parse it and store the string. 618 // Key is a string (standard JSON), parse it and store the string.
609 result = ParseStringHelper(); 619 result = ParseStringHelper();
610 if (result.ok()) { 620 if (result.ok()) {
611 key_storage_.clear(); 621 key_storage_.clear();
612 if (!parsed_storage_.empty()) { 622 if (!parsed_storage_.empty()) {
613 parsed_storage_.swap(key_storage_); 623 parsed_storage_.swap(key_storage_);
614 key_ = StringPiece(key_storage_); 624 key_ = StringPiece(key_storage_);
615 } else { 625 } else {
616 key_ = parsed_; 626 key_ = parsed_;
617 } 627 }
618 parsed_.clear(); 628 parsed_ = StringPiece();
619 } 629 }
620 } else if (type == BEGIN_KEY) { 630 } else if (type == BEGIN_KEY) {
621 // Key is a bare key (back compat), create a StringPiece pointing to it. 631 // Key is a bare key (back compat), create a StringPiece pointing to it.
622 result = ParseKey(); 632 result = ParseKey();
623 } else { 633 } else {
624 // Unknown key type, report an error. 634 // Unknown key type, report an error.
625 result = ReportFailure("Expected an object key or }."); 635 result = ReportFailure("Expected an object key or }.");
626 } 636 }
627 // On success we next expect an entry mid ':' then an object mid ',' or '}' 637 // On success we next expect an entry mid ':' then an object mid ',' or '}'
628 if (result.ok()) { 638 if (result.ok()) {
(...skipping 12 matching lines...) Expand all
641 stack_.push(VALUE); 651 stack_.push(VALUE);
642 return util::Status::OK; 652 return util::Status::OK;
643 } 653 }
644 return ReportFailure("Expected : between key:value pair."); 654 return ReportFailure("Expected : between key:value pair.");
645 } 655 }
646 656
647 util::Status JsonStreamParser::HandleBeginArray() { 657 util::Status JsonStreamParser::HandleBeginArray() {
648 GOOGLE_DCHECK_EQ('[', *p_.data()); 658 GOOGLE_DCHECK_EQ('[', *p_.data());
649 Advance(); 659 Advance();
650 ow_->StartList(key_); 660 ow_->StartList(key_);
651 key_.clear(); 661 key_ = StringPiece();
652 stack_.push(ARRAY_VALUE); 662 stack_.push(ARRAY_VALUE);
653 return util::Status::OK; 663 return util::Status::OK;
654 } 664 }
655 665
656 util::Status JsonStreamParser::ParseArrayValue(TokenType type) { 666 util::Status JsonStreamParser::ParseArrayValue(TokenType type) {
657 if (type == UNKNOWN) { 667 if (type == UNKNOWN) {
658 return ReportUnknown("Expected a value or ] within an array."); 668 return ReportUnknown("Expected a value or ] within an array.");
659 } 669 }
660 670
661 if (type == END_ARRAY) { 671 if (type == END_ARRAY) {
662 ow_->EndList(); 672 ow_->EndList();
663 Advance(); 673 Advance();
664 return util::Status::OK; 674 return util::Status::OK;
665 } 675 }
666 676
667 // The ParseValue call may push something onto the stack so we need to make 677 // The ParseValue call may push something onto the stack so we need to make
668 // sure an ARRAY_MID is after it, so we push it on now. 678 // sure an ARRAY_MID is after it, so we push it on now. Also, the parsing of
679 // empty-null array value is relying on this ARRAY_MID token.
669 stack_.push(ARRAY_MID); 680 stack_.push(ARRAY_MID);
670 util::Status result = ParseValue(type); 681 util::Status result = ParseValue(type);
671 if (result == util::Status::CANCELLED) { 682 if (result == util::Status::CANCELLED) {
672 // If we were cancelled, pop back off the ARRAY_MID so we don't try to 683 // If we were cancelled, pop back off the ARRAY_MID so we don't try to
673 // push it on again when we try over. 684 // push it on again when we try over.
674 stack_.pop(); 685 stack_.pop();
675 } 686 }
676 return result; 687 return result;
677 } 688 }
678 689
(...skipping 13 matching lines...) Expand all
692 Advance(); 703 Advance();
693 stack_.push(ARRAY_VALUE); 704 stack_.push(ARRAY_VALUE);
694 return util::Status::OK; 705 return util::Status::OK;
695 } 706 }
696 // Illegal token after array value. 707 // Illegal token after array value.
697 return ReportFailure("Expected , or ] after array value."); 708 return ReportFailure("Expected , or ] after array value.");
698 } 709 }
699 710
700 util::Status JsonStreamParser::ParseTrue() { 711 util::Status JsonStreamParser::ParseTrue() {
701 ow_->RenderBool(key_, true); 712 ow_->RenderBool(key_, true);
702 key_.clear(); 713 key_ = StringPiece();
703 p_.remove_prefix(true_len); 714 p_.remove_prefix(true_len);
704 return util::Status::OK; 715 return util::Status::OK;
705 } 716 }
706 717
707 util::Status JsonStreamParser::ParseFalse() { 718 util::Status JsonStreamParser::ParseFalse() {
708 ow_->RenderBool(key_, false); 719 ow_->RenderBool(key_, false);
709 key_.clear(); 720 key_ = StringPiece();
710 p_.remove_prefix(false_len); 721 p_.remove_prefix(false_len);
711 return util::Status::OK; 722 return util::Status::OK;
712 } 723 }
713 724
714 util::Status JsonStreamParser::ParseNull() { 725 util::Status JsonStreamParser::ParseNull() {
715 ow_->RenderNull(key_); 726 ow_->RenderNull(key_);
716 key_.clear(); 727 key_ = StringPiece();
717 p_.remove_prefix(null_len); 728 p_.remove_prefix(null_len);
718 return util::Status::OK; 729 return util::Status::OK;
719 } 730 }
720 731
732 util::Status JsonStreamParser::ParseEmptyNull() {
733 ow_->RenderNull(key_);
734 key_ = StringPiece();
735 return util::Status::OK;
736 }
737
738 bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) {
739 if (stack_.empty()) return false;
740 return (stack_.top() == ARRAY_MID && type == VALUE_SEPARATOR) ||
741 stack_.top() == OBJ_MID;
742 }
743
721 util::Status JsonStreamParser::ReportFailure(StringPiece message) { 744 util::Status JsonStreamParser::ReportFailure(StringPiece message) {
722 static const int kContextLength = 20; 745 static const int kContextLength = 20;
723 const char* p_start = p_.data(); 746 const char* p_start = p_.data();
724 const char* json_start = json_.data(); 747 const char* json_start = json_.data();
725 const char* begin = std::max(p_start - kContextLength, json_start); 748 const char* begin = std::max(p_start - kContextLength, json_start);
726 const char* end = 749 const char* end =
727 std::min(p_start + kContextLength, json_start + json_.size()); 750 std::min(p_start + kContextLength, json_start + json_.size());
728 StringPiece segment(begin, end - begin); 751 StringPiece segment(begin, end - begin);
729 string location(p_start - begin, ' '); 752 string location(p_start - begin, ' ');
730 location.push_back('^'); 753 location.push_back('^');
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 // can't parse what we have so far. So we don't report an error and just 834 // can't parse what we have so far. So we don't report an error and just
812 // return UNKNOWN so we can try again later when we have more data, or if we 835 // return UNKNOWN so we can try again later when we have more data, or if we
813 // finish and we have leftovers. 836 // finish and we have leftovers.
814 return UNKNOWN; 837 return UNKNOWN;
815 } 838 }
816 839
817 } // namespace converter 840 } // namespace converter
818 } // namespace util 841 } // namespace util
819 } // namespace protobuf 842 } // namespace protobuf
820 } // namespace google 843 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698