1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <google/protobuf/message.h> 36 37#include <sys/types.h> 38#include <sys/stat.h> 39#include <fcntl.h> 40#ifdef _MSC_VER 41#include <io.h> 42#else 43#include <unistd.h> 44#endif 45#include <sstream> 46#include <fstream> 47 48#include <google/protobuf/io/zero_copy_stream_impl.h> 49#include <google/protobuf/io/coded_stream.h> 50#include <google/protobuf/descriptor.h> 51#include <google/protobuf/descriptor.pb.h> 52#include <google/protobuf/unittest.pb.h> 53#include <google/protobuf/test_util.h> 54 55#include <google/protobuf/stubs/common.h> 56#include <google/protobuf/testing/googletest.h> 57#include <gtest/gtest.h> 58 59namespace google { 60namespace protobuf { 61 62#ifndef O_BINARY 63#ifdef _O_BINARY 64#define O_BINARY _O_BINARY 65#else 66#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. 67#endif 68#endif 69 70TEST(MessageTest, SerializeHelpers) { 71 // TODO(kenton): Test more helpers? They're all two-liners so it seems 72 // like a waste of time. 73 74 protobuf_unittest::TestAllTypes message; 75 TestUtil::SetAllFields(&message); 76 stringstream stream; 77 78 string str1("foo"); 79 string str2("bar"); 80 81 EXPECT_TRUE(message.SerializeToString(&str1)); 82 EXPECT_TRUE(message.AppendToString(&str2)); 83 EXPECT_TRUE(message.SerializeToOstream(&stream)); 84 85 EXPECT_EQ(str1.size() + 3, str2.size()); 86 EXPECT_EQ("bar", str2.substr(0, 3)); 87 // Don't use EXPECT_EQ because we don't want to dump raw binary data to 88 // stdout. 89 EXPECT_TRUE(str2.substr(3) == str1); 90 91 // GCC gives some sort of error if we try to just do stream.str() == str1. 92 string temp = stream.str(); 93 EXPECT_TRUE(temp == str1); 94 95 EXPECT_TRUE(message.SerializeAsString() == str1); 96 97} 98 99TEST(MessageTest, SerializeToBrokenOstream) { 100 ofstream out; 101 protobuf_unittest::TestAllTypes message; 102 message.set_optional_int32(123); 103 104 EXPECT_FALSE(message.SerializeToOstream(&out)); 105} 106 107TEST(MessageTest, ParseFromFileDescriptor) { 108 string filename = TestSourceDir() + 109 "/google/protobuf/testdata/golden_message"; 110 int file = open(filename.c_str(), O_RDONLY | O_BINARY); 111 112 unittest::TestAllTypes message; 113 EXPECT_TRUE(message.ParseFromFileDescriptor(file)); 114 TestUtil::ExpectAllFieldsSet(message); 115 116 EXPECT_GE(close(file), 0); 117} 118 119TEST(MessageTest, ParsePackedFromFileDescriptor) { 120 string filename = 121 TestSourceDir() + 122 "/google/protobuf/testdata/golden_packed_fields_message"; 123 int file = open(filename.c_str(), O_RDONLY | O_BINARY); 124 125 unittest::TestPackedTypes message; 126 EXPECT_TRUE(message.ParseFromFileDescriptor(file)); 127 TestUtil::ExpectPackedFieldsSet(message); 128 129 EXPECT_GE(close(file), 0); 130} 131 132TEST(MessageTest, ParseHelpers) { 133 // TODO(kenton): Test more helpers? They're all two-liners so it seems 134 // like a waste of time. 135 string data; 136 137 { 138 // Set up. 139 protobuf_unittest::TestAllTypes message; 140 TestUtil::SetAllFields(&message); 141 message.SerializeToString(&data); 142 } 143 144 { 145 // Test ParseFromString. 146 protobuf_unittest::TestAllTypes message; 147 EXPECT_TRUE(message.ParseFromString(data)); 148 TestUtil::ExpectAllFieldsSet(message); 149 } 150 151 { 152 // Test ParseFromIstream. 153 protobuf_unittest::TestAllTypes message; 154 stringstream stream(data); 155 EXPECT_TRUE(message.ParseFromIstream(&stream)); 156 EXPECT_TRUE(stream.eof()); 157 TestUtil::ExpectAllFieldsSet(message); 158 } 159 160 { 161 // Test ParseFromBoundedZeroCopyStream. 162 string data_with_junk(data); 163 data_with_junk.append("some junk on the end"); 164 io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size()); 165 protobuf_unittest::TestAllTypes message; 166 EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size())); 167 TestUtil::ExpectAllFieldsSet(message); 168 } 169 170 { 171 // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if 172 // EOF is reached before the expected number of bytes. 173 io::ArrayInputStream stream(data.data(), data.size()); 174 protobuf_unittest::TestAllTypes message; 175 EXPECT_FALSE( 176 message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1)); 177 } 178} 179 180TEST(MessageTest, ParseFailsIfNotInitialized) { 181 unittest::TestRequired message; 182 vector<string> errors; 183 184 { 185 ScopedMemoryLog log; 186 EXPECT_FALSE(message.ParseFromString("")); 187 errors = log.GetMessages(ERROR); 188 } 189 190 ASSERT_EQ(1, errors.size()); 191 EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" " 192 "because it is missing required fields: a, b, c", 193 errors[0]); 194} 195 196TEST(MessageTest, BypassInitializationCheckOnParse) { 197 unittest::TestRequired message; 198 io::ArrayInputStream raw_input(NULL, 0); 199 io::CodedInputStream input(&raw_input); 200 EXPECT_TRUE(message.MergePartialFromCodedStream(&input)); 201} 202 203TEST(MessageTest, InitializationErrorString) { 204 unittest::TestRequired message; 205 EXPECT_EQ("a, b, c", message.InitializationErrorString()); 206} 207 208#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet. 209 210TEST(MessageTest, SerializeFailsIfNotInitialized) { 211 unittest::TestRequired message; 212 string data; 213 EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)), 214 "Can't serialize message of type \"protobuf_unittest.TestRequired\" because " 215 "it is missing required fields: a, b, c"); 216} 217 218TEST(MessageTest, CheckInitialized) { 219 unittest::TestRequired message; 220 EXPECT_DEATH(message.CheckInitialized(), 221 "Message of type \"protobuf_unittest.TestRequired\" is missing required " 222 "fields: a, b, c"); 223} 224 225TEST(MessageTest, CheckOverflow) { 226 unittest::TestAllTypes message; 227 // Create a message with size just over 2GB. This triggers integer overflow 228 // when computing message size. 229 const string data(1024, 'x'); 230 Cord one_megabyte; 231 for (int i = 0; i < 1024; i++) { 232 one_megabyte.Append(data); 233 } 234 235 for (int i = 0; i < 2 * 1024 + 1; ++i) { 236 message.add_repeated_cord()->CopyFrom(one_megabyte); 237 } 238 239 Cord serialized; 240 EXPECT_FALSE(message.AppendToCord(&serialized)); 241} 242 243#endif // PROTOBUF_HAS_DEATH_TEST 244 245TEST(MessageTest, BypassInitializationCheckOnSerialize) { 246 unittest::TestRequired message; 247 io::ArrayOutputStream raw_output(NULL, 0); 248 io::CodedOutputStream output(&raw_output); 249 EXPECT_TRUE(message.SerializePartialToCodedStream(&output)); 250} 251 252TEST(MessageTest, FindInitializationErrors) { 253 unittest::TestRequired message; 254 vector<string> errors; 255 message.FindInitializationErrors(&errors); 256 ASSERT_EQ(3, errors.size()); 257 EXPECT_EQ("a", errors[0]); 258 EXPECT_EQ("b", errors[1]); 259 EXPECT_EQ("c", errors[2]); 260} 261 262TEST(MessageTest, ParseFailsOnInvalidMessageEnd) { 263 unittest::TestAllTypes message; 264 265 // Control case. 266 EXPECT_TRUE(message.ParseFromArray("", 0)); 267 268 // The byte is a valid varint, but not a valid tag (zero). 269 EXPECT_FALSE(message.ParseFromArray("\0", 1)); 270 271 // The byte is a malformed varint. 272 EXPECT_FALSE(message.ParseFromArray("\200", 1)); 273 274 // The byte is an endgroup tag, but we aren't parsing a group. 275 EXPECT_FALSE(message.ParseFromArray("\014", 1)); 276} 277 278namespace { 279 280void ExpectMessageMerged(const unittest::TestAllTypes& message) { 281 EXPECT_EQ(3, message.optional_int32()); 282 EXPECT_EQ(2, message.optional_int64()); 283 EXPECT_EQ("hello", message.optional_string()); 284} 285 286void AssignParsingMergeMessages( 287 unittest::TestAllTypes* msg1, 288 unittest::TestAllTypes* msg2, 289 unittest::TestAllTypes* msg3) { 290 msg1->set_optional_int32(1); 291 msg2->set_optional_int64(2); 292 msg3->set_optional_int32(3); 293 msg3->set_optional_string("hello"); 294} 295 296} // namespace 297 298// Test that if an optional or required message/group field appears multiple 299// times in the input, they need to be merged. 300TEST(MessageTest, ParsingMerge) { 301 unittest::TestParsingMerge::RepeatedFieldsGenerator generator; 302 unittest::TestAllTypes* msg1; 303 unittest::TestAllTypes* msg2; 304 unittest::TestAllTypes* msg3; 305 306#define ASSIGN_REPEATED_FIELD(FIELD) \ 307 msg1 = generator.add_##FIELD(); \ 308 msg2 = generator.add_##FIELD(); \ 309 msg3 = generator.add_##FIELD(); \ 310 AssignParsingMergeMessages(msg1, msg2, msg3) 311 312 ASSIGN_REPEATED_FIELD(field1); 313 ASSIGN_REPEATED_FIELD(field2); 314 ASSIGN_REPEATED_FIELD(field3); 315 ASSIGN_REPEATED_FIELD(ext1); 316 ASSIGN_REPEATED_FIELD(ext2); 317 318#undef ASSIGN_REPEATED_FIELD 319#define ASSIGN_REPEATED_GROUP(FIELD) \ 320 msg1 = generator.add_##FIELD()->mutable_field1(); \ 321 msg2 = generator.add_##FIELD()->mutable_field1(); \ 322 msg3 = generator.add_##FIELD()->mutable_field1(); \ 323 AssignParsingMergeMessages(msg1, msg2, msg3) 324 325 ASSIGN_REPEATED_GROUP(group1); 326 ASSIGN_REPEATED_GROUP(group2); 327 328#undef ASSIGN_REPEATED_GROUP 329 330 string buffer; 331 generator.SerializeToString(&buffer); 332 unittest::TestParsingMerge parsing_merge; 333 parsing_merge.ParseFromString(buffer); 334 335 // Required and optional fields should be merged. 336 ExpectMessageMerged(parsing_merge.required_all_types()); 337 ExpectMessageMerged(parsing_merge.optional_all_types()); 338 ExpectMessageMerged( 339 parsing_merge.optionalgroup().optional_group_all_types()); 340 ExpectMessageMerged( 341 parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext)); 342 343 // Repeated fields should not be merged. 344 EXPECT_EQ(3, parsing_merge.repeated_all_types_size()); 345 EXPECT_EQ(3, parsing_merge.repeatedgroup_size()); 346 EXPECT_EQ(3, parsing_merge.ExtensionSize( 347 unittest::TestParsingMerge::repeated_ext)); 348} 349 350TEST(MessageTest, MergeFrom) { 351 unittest::TestAllTypes source; 352 unittest::TestAllTypes dest; 353 354 // Optional fields 355 source.set_optional_int32(1); // only source 356 source.set_optional_int64(2); // both source and dest 357 dest.set_optional_int64(3); 358 dest.set_optional_uint32(4); // only dest 359 360 // Optional fields with defaults 361 source.set_default_int32(13); // only source 362 source.set_default_int64(14); // both source and dest 363 dest.set_default_int64(15); 364 dest.set_default_uint32(16); // only dest 365 366 // Repeated fields 367 source.add_repeated_int32(5); // only source 368 source.add_repeated_int32(6); 369 source.add_repeated_int64(7); // both source and dest 370 source.add_repeated_int64(8); 371 dest.add_repeated_int64(9); 372 dest.add_repeated_int64(10); 373 dest.add_repeated_uint32(11); // only dest 374 dest.add_repeated_uint32(12); 375 376 dest.MergeFrom(source); 377 378 // Optional fields: source overwrites dest if source is specified 379 EXPECT_EQ(1, dest.optional_int32()); // only source: use source 380 EXPECT_EQ(2, dest.optional_int64()); // source and dest: use source 381 EXPECT_EQ(4, dest.optional_uint32()); // only dest: use dest 382 EXPECT_EQ(0, dest.optional_uint64()); // neither: use default 383 384 // Optional fields with defaults 385 EXPECT_EQ(13, dest.default_int32()); // only source: use source 386 EXPECT_EQ(14, dest.default_int64()); // source and dest: use source 387 EXPECT_EQ(16, dest.default_uint32()); // only dest: use dest 388 EXPECT_EQ(44, dest.default_uint64()); // neither: use default 389 390 // Repeated fields: concatenate source onto the end of dest 391 ASSERT_EQ(2, dest.repeated_int32_size()); 392 EXPECT_EQ(5, dest.repeated_int32(0)); 393 EXPECT_EQ(6, dest.repeated_int32(1)); 394 ASSERT_EQ(4, dest.repeated_int64_size()); 395 EXPECT_EQ(9, dest.repeated_int64(0)); 396 EXPECT_EQ(10, dest.repeated_int64(1)); 397 EXPECT_EQ(7, dest.repeated_int64(2)); 398 EXPECT_EQ(8, dest.repeated_int64(3)); 399 ASSERT_EQ(2, dest.repeated_uint32_size()); 400 EXPECT_EQ(11, dest.repeated_uint32(0)); 401 EXPECT_EQ(12, dest.repeated_uint32(1)); 402 ASSERT_EQ(0, dest.repeated_uint64_size()); 403} 404 405TEST(MessageFactoryTest, GeneratedFactoryLookup) { 406 EXPECT_EQ( 407 MessageFactory::generated_factory()->GetPrototype( 408 protobuf_unittest::TestAllTypes::descriptor()), 409 &protobuf_unittest::TestAllTypes::default_instance()); 410} 411 412TEST(MessageFactoryTest, GeneratedFactoryUnknownType) { 413 // Construct a new descriptor. 414 DescriptorPool pool; 415 FileDescriptorProto file; 416 file.set_name("foo.proto"); 417 file.add_message_type()->set_name("Foo"); 418 const Descriptor* descriptor = pool.BuildFile(file)->message_type(0); 419 420 // Trying to construct it should return NULL. 421 EXPECT_TRUE( 422 MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL); 423} 424 425 426} // namespace protobuf 427} // namespace google 428