aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeng Xiao <xiaofeng@google.com>2016-05-04 10:55:13 -0700
committerFeng Xiao <xiaofeng@google.com>2016-05-04 10:55:13 -0700
commit17b6fc31eb8a9b65501cd7c53235a88efdc94394 (patch)
tree20b5c3cc69f7643b139a9d498563f9cabbbf34b6
parent72e162ce96fcd153654a1ab7a26b67ab7278580b (diff)
parentf4f9aec52f5b4c46ff32fb9527229da081a14e11 (diff)
downloadprotobuf-17b6fc31eb8a9b65501cd7c53235a88efdc94394.tar.gz
protobuf-17b6fc31eb8a9b65501cd7c53235a88efdc94394.tar.bz2
protobuf-17b6fc31eb8a9b65501cd7c53235a88efdc94394.zip
Merge pull request #1409 from eeight/fix_enum_corruption
Fix bug with silent message corruption in LITE_RUNTIME.
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc6
-rw-r--r--src/google/protobuf/lite_unittest.cc27
-rw-r--r--src/google/protobuf/unittest_lite.proto19
3 files changed, 50 insertions, 2 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 78a4c402..10252b39 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -36,6 +36,7 @@
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/wire_format.h>
namespace google {
namespace protobuf {
@@ -141,8 +142,9 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
} else {
printer->Print(
"} else {\n"
- " unknown_fields_stream.WriteVarint32(tag);\n"
- " unknown_fields_stream.WriteVarint32(value);\n");
+ " unknown_fields_stream.WriteVarint32($tag$);\n"
+ " unknown_fields_stream.WriteVarint32(value);\n",
+ "tag", SimpleItoa(internal::WireFormat::MakeTag(descriptor_)));
}
printer->Print(variables_,
"}\n");
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index d1948ab5..3ca3fbaf 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -686,6 +686,33 @@ int main(int argc, char* argv[]) {
EXPECT_TRUE(map_message.IsInitialized());
}
+ {
+ // Check that adding more values to enum does not corrupt message
+ // when passed through an old client.
+ protobuf_unittest::V2MessageLite v2_message;
+ v2_message.set_int_field(800);
+ // Set enum field to the value not understood by the old client.
+ v2_message.set_enum_field(protobuf_unittest::V2_SECOND);
+ string v2_bytes = v2_message.SerializeAsString();
+
+ protobuf_unittest::V1MessageLite v1_message;
+ v1_message.ParseFromString(v2_bytes);
+ EXPECT_TRUE(v1_message.IsInitialized());
+ EXPECT_EQ(v1_message.int_field(), v2_message.int_field());
+ // V1 client does not understand V2_SECOND value, so it discards it and
+ // uses default value instead.
+ EXPECT_EQ(v1_message.enum_field(), protobuf_unittest::V1_FIRST);
+
+ // However, when re-serialized, it should preserve enum value.
+ string v1_bytes = v1_message.SerializeAsString();
+
+ protobuf_unittest::V2MessageLite same_v2_message;
+ same_v2_message.ParseFromString(v1_bytes);
+
+ EXPECT_EQ(v2_message.int_field(), same_v2_message.int_field());
+ EXPECT_EQ(v2_message.enum_field(), same_v2_message.enum_field());
+ }
+
std::cout << "PASS" << std::endl;
return 0;
}
diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto
index 41ed845f..878ec7c1 100644
--- a/src/google/protobuf/unittest_lite.proto
+++ b/src/google/protobuf/unittest_lite.proto
@@ -386,3 +386,22 @@ message TestEmptyMessageLite{
message TestEmptyMessageWithExtensionsLite {
extensions 1 to max;
}
+
+enum V1EnumLite {
+ V1_FIRST = 1;
+}
+
+enum V2EnumLite {
+ V2_FIRST = 1;
+ V2_SECOND = 2;
+}
+
+message V1MessageLite {
+ required int32 int_field = 1;
+ optional V1EnumLite enum_field = 2 [ default = V1_FIRST ];
+}
+
+message V2MessageLite {
+ required int32 int_field = 1;
+ optional V2EnumLite enum_field = 2 [ default = V2_FIRST ];
+}