aboutsummaryrefslogtreecommitdiffstats
path: root/src/google/protobuf/message_unittest.cc
diff options
context:
space:
mode:
authorJeff Davidson <jpd@google.com>2014-09-15 16:29:06 -0700
committerJeff Davidson <jpd@google.com>2015-01-15 14:10:53 -0800
commita3b2a6da25a76f17c73d31def3952feb0fd2296e (patch)
tree586f7d5e9a7e05af45d0e821188097c0faa96219 /src/google/protobuf/message_unittest.cc
parentc7c25812eb19d080087b71e08bfe35aff9f21433 (diff)
downloadexternal_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.zip
external_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.tar.gz
external_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.tar.bz2
Update protobuf library from 2.3 to 2.6.
Copied in all files from the open source protobuf project at commit edc5994525c79cd1919859a370837a6ff7c8e308, removing files which have been renamed (COPYING.txt -> LICENSE, README.txt -> README.md). Removed 2.3 prebuilts, which is an approach that will not work due to incompatibility with the 2.6 runtime. Merged in micro/nano-specific changes in the following files: -Android.mk - updated list of C++/Java sources, bumped versions -java/README.txt - merged in micro/nano instructions, bumped versions -java/pom.xml - merged in micro/nano build rules, set packaging to jar -src/Makefile.am - merged in references to micro/nano generators -src/google/protobuf/compiler/javamicro/javamicro_file.h - imported google/protobuf/compiler/code_generator.h and removed redundant OutputDirectory class. -src/google/protobuf/compiler/javanano/javanano_file.h - same -Replaced instances of vector with std::vector as needed to get libprotobuf-cpp-full to compile. Plan to upstream this fix per discussion with protobuf maintainers. Reran autogen.sh to update ./configure and associated scripts. Change-Id: I949d32fb5126f1c05e2a6ed48f6636a4a9b15a48
Diffstat (limited to 'src/google/protobuf/message_unittest.cc')
-rw-r--r--src/google/protobuf/message_unittest.cc152
1 files changed, 149 insertions, 3 deletions
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 33b9e77..8b6fd6f 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -45,7 +45,6 @@
#include <sstream>
#include <fstream>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.h>
@@ -53,6 +52,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -205,7 +205,7 @@ TEST(MessageTest, InitializationErrorString) {
EXPECT_EQ("a, b, c", message.InitializationErrorString());
}
-#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet.
TEST(MessageTest, SerializeFailsIfNotInitialized) {
unittest::TestRequired message;
@@ -222,7 +222,25 @@ TEST(MessageTest, CheckInitialized) {
"fields: a, b, c");
}
-#endif // GTEST_HAS_DEATH_TEST
+TEST(MessageTest, CheckOverflow) {
+ unittest::TestAllTypes message;
+ // Create a message with size just over 2GB. This triggers integer overflow
+ // when computing message size.
+ const string data(1024, 'x');
+ Cord one_megabyte;
+ for (int i = 0; i < 1024; i++) {
+ one_megabyte.Append(data);
+ }
+
+ for (int i = 0; i < 2 * 1024 + 1; ++i) {
+ message.add_repeated_cord()->CopyFrom(one_megabyte);
+ }
+
+ Cord serialized;
+ EXPECT_FALSE(message.AppendToCord(&serialized));
+}
+
+#endif // PROTOBUF_HAS_DEATH_TEST
TEST(MessageTest, BypassInitializationCheckOnSerialize) {
unittest::TestRequired message;
@@ -257,6 +275,133 @@ TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
EXPECT_FALSE(message.ParseFromArray("\014", 1));
}
+namespace {
+
+void ExpectMessageMerged(const unittest::TestAllTypes& message) {
+ EXPECT_EQ(3, message.optional_int32());
+ EXPECT_EQ(2, message.optional_int64());
+ EXPECT_EQ("hello", message.optional_string());
+}
+
+void AssignParsingMergeMessages(
+ unittest::TestAllTypes* msg1,
+ unittest::TestAllTypes* msg2,
+ unittest::TestAllTypes* msg3) {
+ msg1->set_optional_int32(1);
+ msg2->set_optional_int64(2);
+ msg3->set_optional_int32(3);
+ msg3->set_optional_string("hello");
+}
+
+} // namespace
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+TEST(MessageTest, ParsingMerge) {
+ unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
+ unittest::TestAllTypes* msg1;
+ unittest::TestAllTypes* msg2;
+ unittest::TestAllTypes* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD) \
+ msg1 = generator.add_##FIELD(); \
+ msg2 = generator.add_##FIELD(); \
+ msg3 = generator.add_##FIELD(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_FIELD(field1);
+ ASSIGN_REPEATED_FIELD(field2);
+ ASSIGN_REPEATED_FIELD(field3);
+ ASSIGN_REPEATED_FIELD(ext1);
+ ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD) \
+ msg1 = generator.add_##FIELD()->mutable_field1(); \
+ msg2 = generator.add_##FIELD()->mutable_field1(); \
+ msg3 = generator.add_##FIELD()->mutable_field1(); \
+ AssignParsingMergeMessages(msg1, msg2, msg3)
+
+ ASSIGN_REPEATED_GROUP(group1);
+ ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+ string buffer;
+ generator.SerializeToString(&buffer);
+ unittest::TestParsingMerge parsing_merge;
+ parsing_merge.ParseFromString(buffer);
+
+ // Required and optional fields should be merged.
+ ExpectMessageMerged(parsing_merge.required_all_types());
+ ExpectMessageMerged(parsing_merge.optional_all_types());
+ ExpectMessageMerged(
+ parsing_merge.optionalgroup().optional_group_all_types());
+ ExpectMessageMerged(
+ parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
+
+ // Repeated fields should not be merged.
+ EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
+ EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
+ EXPECT_EQ(3, parsing_merge.ExtensionSize(
+ unittest::TestParsingMerge::repeated_ext));
+}
+
+TEST(MessageTest, MergeFrom) {
+ unittest::TestAllTypes source;
+ unittest::TestAllTypes dest;
+
+ // Optional fields
+ source.set_optional_int32(1); // only source
+ source.set_optional_int64(2); // both source and dest
+ dest.set_optional_int64(3);
+ dest.set_optional_uint32(4); // only dest
+
+ // Optional fields with defaults
+ source.set_default_int32(13); // only source
+ source.set_default_int64(14); // both source and dest
+ dest.set_default_int64(15);
+ dest.set_default_uint32(16); // only dest
+
+ // Repeated fields
+ source.add_repeated_int32(5); // only source
+ source.add_repeated_int32(6);
+ source.add_repeated_int64(7); // both source and dest
+ source.add_repeated_int64(8);
+ dest.add_repeated_int64(9);
+ dest.add_repeated_int64(10);
+ dest.add_repeated_uint32(11); // only dest
+ dest.add_repeated_uint32(12);
+
+ dest.MergeFrom(source);
+
+ // Optional fields: source overwrites dest if source is specified
+ EXPECT_EQ(1, dest.optional_int32()); // only source: use source
+ EXPECT_EQ(2, dest.optional_int64()); // source and dest: use source
+ EXPECT_EQ(4, dest.optional_uint32()); // only dest: use dest
+ EXPECT_EQ(0, dest.optional_uint64()); // neither: use default
+
+ // Optional fields with defaults
+ EXPECT_EQ(13, dest.default_int32()); // only source: use source
+ EXPECT_EQ(14, dest.default_int64()); // source and dest: use source
+ EXPECT_EQ(16, dest.default_uint32()); // only dest: use dest
+ EXPECT_EQ(44, dest.default_uint64()); // neither: use default
+
+ // Repeated fields: concatenate source onto the end of dest
+ ASSERT_EQ(2, dest.repeated_int32_size());
+ EXPECT_EQ(5, dest.repeated_int32(0));
+ EXPECT_EQ(6, dest.repeated_int32(1));
+ ASSERT_EQ(4, dest.repeated_int64_size());
+ EXPECT_EQ(9, dest.repeated_int64(0));
+ EXPECT_EQ(10, dest.repeated_int64(1));
+ EXPECT_EQ(7, dest.repeated_int64(2));
+ EXPECT_EQ(8, dest.repeated_int64(3));
+ ASSERT_EQ(2, dest.repeated_uint32_size());
+ EXPECT_EQ(11, dest.repeated_uint32(0));
+ EXPECT_EQ(12, dest.repeated_uint32(1));
+ ASSERT_EQ(0, dest.repeated_uint64_size());
+}
+
TEST(MessageFactoryTest, GeneratedFactoryLookup) {
EXPECT_EQ(
MessageFactory::generated_factory()->GetPrototype(
@@ -277,5 +422,6 @@ TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
}
+
} // namespace protobuf
} // namespace google