diff options
author | Feng Xiao <xiaofeng@google.com> | 2016-05-04 10:55:13 -0700 |
---|---|---|
committer | Feng Xiao <xiaofeng@google.com> | 2016-05-04 10:55:13 -0700 |
commit | 17b6fc31eb8a9b65501cd7c53235a88efdc94394 (patch) | |
tree | 20b5c3cc69f7643b139a9d498563f9cabbbf34b6 /src/google | |
parent | 72e162ce96fcd153654a1ab7a26b67ab7278580b (diff) | |
parent | f4f9aec52f5b4c46ff32fb9527229da081a14e11 (diff) | |
download | protobuf-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.
Diffstat (limited to 'src/google')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_enum_field.cc | 6 | ||||
-rw-r--r-- | src/google/protobuf/lite_unittest.cc | 27 | ||||
-rw-r--r-- | src/google/protobuf/unittest_lite.proto | 19 |
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 ]; +} |