aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Adam Cozzette <acozzette@google.com>2018-03-13 16:54:31 -0700
committerGravatar Adam Cozzette <acozzette@google.com>2018-03-13 16:54:31 -0700
commitafe96b6d4235b9d9fbfce2465f5c6d82c2611f48 (patch)
treed509cb3cc3f2b25b58a75563758d2092103ca19a /src
parent0400cca3236de1ca303af38bf81eab332d042b7c (diff)
parent89b5333ad0f10058d5af62701c5ebea0db376c5b (diff)
Merge branch 'master' into down-integrate
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/arena.h2
-rw-r--r--src/google/protobuf/compiler/js/embed.cc2
-rw-r--r--src/google/protobuf/map_entry_lite.h4
-rw-r--r--src/google/protobuf/stubs/hash.h3
-rw-r--r--src/google/protobuf/util/internal/datapiece.cc7
-rw-r--r--src/google/protobuf/util/internal/datapiece.h3
-rw-r--r--src/google/protobuf/util/internal/proto_writer.cc8
-rw-r--r--src/google/protobuf/util/internal/proto_writer.h2
-rw-r--r--src/google/protobuf/util/json_util_test.cc58
9 files changed, 77 insertions, 12 deletions
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 53b7def5..f286ada8 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -37,7 +37,7 @@
#ifdef max
#undef max // Visual Studio defines this macro
#endif
-#if defined(_MSC_VER) && !_HAS_EXCEPTIONS
+#if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS
// Work around bugs in MSVC <typeinfo> header when _HAS_EXCEPTIONS=0.
#include <exception>
#include <typeinfo>
diff --git a/src/google/protobuf/compiler/js/embed.cc b/src/google/protobuf/compiler/js/embed.cc
index a725b62e..f0f946e5 100644
--- a/src/google/protobuf/compiler/js/embed.cc
+++ b/src/google/protobuf/compiler/js/embed.cc
@@ -34,8 +34,6 @@
#include <iostream>
#include <string>
-const char output_file[] = "well_known_types_embed.cc";
-
static bool AsciiIsPrint(unsigned char c) {
return c >= 32 && c < 127;
}
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index aa8ff390..85a0bed7 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -355,9 +355,9 @@ class MapEntryImpl : public Base {
// We could use memcmp here, but we don't bother. The tag is one byte.
GOOGLE_COMPILE_ASSERT(kTagSize == 1, tag_size_error);
if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) {
- typename Map::size_type size = map_->size();
+ typename Map::size_type map_size = map_->size();
value_ptr_ = &(*map_)[key_];
- if (GOOGLE_PREDICT_TRUE(size != map_->size())) {
+ if (GOOGLE_PREDICT_TRUE(map_size != map_->size())) {
// We created a new key-value pair. Fill in the value.
typedef
typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T;
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index daf8ec57..d04a25e1 100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -235,7 +235,8 @@ class hash_set : public std::set<Key, HashFcn> {
HashFcn hash_function() const { return HashFcn(); }
};
-#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
+#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) && \
+ !(defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11)
template <typename Key>
struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index 2f4242d5..59bc28ae 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -272,7 +272,8 @@ StatusOr<string> DataPiece::ToBytes() const {
}
StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type,
- bool use_lower_camel_for_enums) const {
+ bool use_lower_camel_for_enums,
+ bool ignore_unknown_enum_values) const {
if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE;
if (type_ == TYPE_STRING) {
@@ -305,6 +306,10 @@ StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type,
value = FindEnumValueByNameWithoutUnderscoreOrNull(enum_type, enum_name);
if (value != nullptr) return value->number();
}
+
+ // If ignore_unknown_enum_values is true an unknown enum value is treated
+ // as the default
+ if (ignore_unknown_enum_values) return enum_type->enumvalue(0).number();
} else {
// We don't need to check whether the value is actually declared in the
// enum because we preserve unknown enum values as well.
diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h
index 83516d09..95b133da 100644
--- a/src/google/protobuf/util/internal/datapiece.h
+++ b/src/google/protobuf/util/internal/datapiece.h
@@ -164,7 +164,8 @@ class LIBPROTOBUF_EXPORT DataPiece {
// If the value is not a string, attempts to convert to a 32-bit integer.
// If none of these succeeds, returns a conversion error status.
util::StatusOr<int> ToEnum(const google::protobuf::Enum* enum_type,
- bool use_lower_camel_for_enums) const;
+ bool use_lower_camel_for_enums,
+ bool ignore_unknown_enum_values) const;
private:
// Disallow implicit constructor.
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index 9107e404..b7a52db6 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -267,8 +267,9 @@ inline Status WriteString(int field_number, const DataPiece& data,
inline Status WriteEnum(int field_number, const DataPiece& data,
const google::protobuf::Enum* enum_type,
CodedOutputStream* stream,
- bool use_lower_camel_for_enums) {
- StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums);
+ bool use_lower_camel_for_enums,
+ bool ignore_unknown_values) {
+ StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums, ignore_unknown_values);
if (e.ok()) {
WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
}
@@ -665,7 +666,8 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
case google::protobuf::Field_Kind_TYPE_ENUM: {
status = WriteEnum(field.number(), data,
typeinfo_->GetEnumByTypeUrl(field.type_url()),
- stream_.get(), use_lower_camel_for_enums_);
+ stream_.get(), use_lower_camel_for_enums_,
+ ignore_unknown_fields_);
break;
}
default: // TYPE_GROUP or TYPE_MESSAGE
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index 89ca0e86..28496963 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -309,7 +309,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// Indicates whether we finished writing root message completely.
bool done_;
- // If true, don't report unknown field names to the listener.
+ // If true, don't report unknown field names and enum values to the listener.
bool ignore_unknown_fields_;
// If true, check if enum name in camel case or without underscore matches the
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index 8c8380dc..dbd262f6 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -333,6 +333,64 @@ TEST_F(JsonUtilTest, TestDynamicMessage) {
EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
}
+TEST_F(JsonUtilTest, TestParsingUnknownEnumsAs0) {
+ TestMessage m;
+ {
+ JsonParseOptions options;
+ ASSERT_FALSE(options.ignore_unknown_fields);
+ string input =
+ "{\n"
+ " \"enum_value\":\"UNKNOWN_VALUE\"\n"
+ "}";
+ m.set_enum_value(proto3::BAR);
+ EXPECT_FALSE(FromJson(input, &m, options));
+ ASSERT_EQ(proto3::BAR, m.enum_value()); // Keep previous value
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+ EXPECT_EQ(0, m.enum_value()); // Unknown enum value must be decoded as 0
+ }
+ // Integer values are read as usual
+ {
+ JsonParseOptions options;
+ string input =
+ "{\n"
+ " \"enum_value\":12345\n"
+ "}";
+ m.set_enum_value(proto3::BAR);
+ EXPECT_TRUE(FromJson(input, &m, options));
+ ASSERT_EQ(12345, m.enum_value());
+
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson(input, &m, options));
+ EXPECT_EQ(12345, m.enum_value());
+ }
+
+ // Trying to pass an object as an enum field value is always treated as an error
+ {
+ JsonParseOptions options;
+ string input =
+ "{\n"
+ " \"enum_value\":{}\n"
+ "}";
+ options.ignore_unknown_fields = true;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ options.ignore_unknown_fields = false;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ }
+ // Trying to pass an array as an enum field value is always treated as an error
+ {
+ JsonParseOptions options;
+ string input =
+ "{\n"
+ " \"enum_value\":[]\n"
+ "}";
+ EXPECT_FALSE(FromJson(input, &m, options));
+ options.ignore_unknown_fields = true;
+ EXPECT_FALSE(FromJson(input, &m, options));
+ }
+}
+
typedef std::pair<char*, int> Segment;
// A ZeroCopyOutputStream that writes to multiple buffers.
class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {