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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc
diff --git a/third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc b/third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc
index 39be7b03900ab908816cda7e01a53cadae8e478d..2af4ad90a41e1601f1a3c36160399fb77df09e7d 100644
--- a/third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -45,6 +45,8 @@
#include <google/protobuf/util/internal/object_writer.h>
#include <google/protobuf/util/internal/json_escaping.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/mathlimits.h>
+
namespace google {
namespace protobuf {
@@ -107,7 +109,9 @@ JsonStreamParser::JsonStreamParser(ObjectWriter* ow)
parsed_storage_(),
string_open_(0),
chunk_storage_(),
- coerce_to_utf8_(false) {
+ coerce_to_utf8_(false),
+ allow_empty_null_(false),
+ loose_float_number_conversion_(false) {
// Initialize the stack with a single value to be parsed.
stack_.push(VALUE);
}
@@ -277,6 +281,10 @@ util::Status JsonStreamParser::ParseValue(TokenType type) {
case UNKNOWN:
return ReportUnknown("Expected a value.");
default: {
+ if (allow_empty_null_ && IsEmptyNullAllowed(type)) {
+ return ParseEmptyNull();
+ }
+
// Special case for having been cut off while parsing, wait for more data.
// This handles things like 'fals' being at the end of the string, we
// don't know if the next char would be e, completing it, or something
@@ -293,8 +301,8 @@ util::Status JsonStreamParser::ParseString() {
util::Status result = ParseStringHelper();
if (result.ok()) {
ow_->RenderString(key_, parsed_);
- key_.clear();
- parsed_.clear();
+ key_ = StringPiece();
+ parsed_ = StringPiece();
parsed_storage_.clear();
}
return result;
@@ -315,7 +323,6 @@ util::Status JsonStreamParser::ParseStringHelper() {
// We're about to handle an escape, copy all bytes from last to data.
if (last < data) {
parsed_storage_.append(last, data - last);
- last = data;
}
// If we ran out of string after the \, cancel or report an error
// depending on if we expect more data later.
@@ -371,7 +378,6 @@ util::Status JsonStreamParser::ParseStringHelper() {
} else {
if (last < data) {
parsed_storage_.append(last, data - last);
- last = data;
}
parsed_ = StringPiece(parsed_storage_);
}
@@ -471,17 +477,17 @@ util::Status JsonStreamParser::ParseNumber() {
switch (number.type) {
case NumberResult::DOUBLE:
ow_->RenderDouble(key_, number.double_val);
- key_.clear();
+ key_ = StringPiece();
break;
case NumberResult::INT:
ow_->RenderInt64(key_, number.int_val);
- key_.clear();
+ key_ = StringPiece();
break;
case NumberResult::UINT:
ow_->RenderUint64(key_, number.uint_val);
- key_.clear();
+ key_ = StringPiece();
break;
default:
@@ -529,6 +535,10 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
if (!safe_strtod(number, &result->double_val)) {
return ReportFailure("Unable to parse number.");
}
+ if (!loose_float_number_conversion_ &&
+ !MathLimits<double>::IsFinite(result->double_val)) {
+ return ReportFailure("Number exceeds the range of double.");
+ }
result->type = NumberResult::DOUBLE;
p_.remove_prefix(index);
return util::Status::OK;
@@ -565,7 +575,7 @@ util::Status JsonStreamParser::HandleBeginObject() {
GOOGLE_DCHECK_EQ('{', *p_.data());
Advance();
ow_->StartObject(key_);
- key_.clear();
+ key_ = StringPiece();
stack_.push(ENTRY);
return util::Status::OK;
}
@@ -615,7 +625,7 @@ util::Status JsonStreamParser::ParseEntry(TokenType type) {
} else {
key_ = parsed_;
}
- parsed_.clear();
+ parsed_ = StringPiece();
}
} else if (type == BEGIN_KEY) {
// Key is a bare key (back compat), create a StringPiece pointing to it.
@@ -648,7 +658,7 @@ util::Status JsonStreamParser::HandleBeginArray() {
GOOGLE_DCHECK_EQ('[', *p_.data());
Advance();
ow_->StartList(key_);
- key_.clear();
+ key_ = StringPiece();
stack_.push(ARRAY_VALUE);
return util::Status::OK;
}
@@ -665,7 +675,8 @@ util::Status JsonStreamParser::ParseArrayValue(TokenType type) {
}
// The ParseValue call may push something onto the stack so we need to make
- // sure an ARRAY_MID is after it, so we push it on now.
+ // sure an ARRAY_MID is after it, so we push it on now. Also, the parsing of
+ // empty-null array value is relying on this ARRAY_MID token.
stack_.push(ARRAY_MID);
util::Status result = ParseValue(type);
if (result == util::Status::CANCELLED) {
@@ -699,25 +710,37 @@ util::Status JsonStreamParser::ParseArrayMid(TokenType type) {
util::Status JsonStreamParser::ParseTrue() {
ow_->RenderBool(key_, true);
- key_.clear();
+ key_ = StringPiece();
p_.remove_prefix(true_len);
return util::Status::OK;
}
util::Status JsonStreamParser::ParseFalse() {
ow_->RenderBool(key_, false);
- key_.clear();
+ key_ = StringPiece();
p_.remove_prefix(false_len);
return util::Status::OK;
}
util::Status JsonStreamParser::ParseNull() {
ow_->RenderNull(key_);
- key_.clear();
+ key_ = StringPiece();
p_.remove_prefix(null_len);
return util::Status::OK;
}
+util::Status JsonStreamParser::ParseEmptyNull() {
+ ow_->RenderNull(key_);
+ key_ = StringPiece();
+ return util::Status::OK;
+}
+
+bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) {
+ if (stack_.empty()) return false;
+ return (stack_.top() == ARRAY_MID && type == VALUE_SEPARATOR) ||
+ stack_.top() == OBJ_MID;
+}
+
util::Status JsonStreamParser::ReportFailure(StringPiece message) {
static const int kContextLength = 20;
const char* p_start = p_.data();

Powered by Google App Engine
This is Rietveld 408576698