• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test_util.h>
49 #include <google/protobuf/unittest.pb.h>
50 #include <google/protobuf/io/coded_stream.h>
51 #include <google/protobuf/io/zero_copy_stream_impl.h>
52 #include <google/protobuf/descriptor.pb.h>
53 #include <google/protobuf/descriptor.h>
54 #include <google/protobuf/generated_message_reflection.h>
55 
56 #include <google/protobuf/stubs/logging.h>
57 #include <google/protobuf/stubs/common.h>
58 #include <google/protobuf/stubs/logging.h>
59 #include <google/protobuf/testing/googletest.h>
60 #include <gtest/gtest.h>
61 
62 namespace google {
63 namespace protobuf {
64 
65 #ifndef O_BINARY
66 #ifdef _O_BINARY
67 #define O_BINARY _O_BINARY
68 #else
69 #define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
70 #endif
71 #endif
72 
TEST(MessageTest,SerializeHelpers)73 TEST(MessageTest, SerializeHelpers) {
74   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
75   //   like a waste of time.
76 
77   protobuf_unittest::TestAllTypes message;
78   TestUtil::SetAllFields(&message);
79   stringstream stream;
80 
81   string str1("foo");
82   string str2("bar");
83 
84   EXPECT_TRUE(message.SerializeToString(&str1));
85   EXPECT_TRUE(message.AppendToString(&str2));
86   EXPECT_TRUE(message.SerializeToOstream(&stream));
87 
88   EXPECT_EQ(str1.size() + 3, str2.size());
89   EXPECT_EQ("bar", str2.substr(0, 3));
90   // Don't use EXPECT_EQ because we don't want to dump raw binary data to
91   // stdout.
92   EXPECT_TRUE(str2.substr(3) == str1);
93 
94   // GCC gives some sort of error if we try to just do stream.str() == str1.
95   string temp = stream.str();
96   EXPECT_TRUE(temp == str1);
97 
98   EXPECT_TRUE(message.SerializeAsString() == str1);
99 
100 }
101 
TEST(MessageTest,SerializeToBrokenOstream)102 TEST(MessageTest, SerializeToBrokenOstream) {
103   ofstream out;
104   protobuf_unittest::TestAllTypes message;
105   message.set_optional_int32(123);
106 
107   EXPECT_FALSE(message.SerializeToOstream(&out));
108 }
109 
TEST(MessageTest,ParseFromFileDescriptor)110 TEST(MessageTest, ParseFromFileDescriptor) {
111   string filename = TestSourceDir() +
112                     "/google/protobuf/testdata/golden_message";
113   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
114 
115   unittest::TestAllTypes message;
116   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
117   TestUtil::ExpectAllFieldsSet(message);
118 
119   EXPECT_GE(close(file), 0);
120 }
121 
TEST(MessageTest,ParsePackedFromFileDescriptor)122 TEST(MessageTest, ParsePackedFromFileDescriptor) {
123   string filename =
124       TestSourceDir() +
125       "/google/protobuf/testdata/golden_packed_fields_message";
126   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
127 
128   unittest::TestPackedTypes message;
129   EXPECT_TRUE(message.ParseFromFileDescriptor(file));
130   TestUtil::ExpectPackedFieldsSet(message);
131 
132   EXPECT_GE(close(file), 0);
133 }
134 
TEST(MessageTest,ParseHelpers)135 TEST(MessageTest, ParseHelpers) {
136   // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
137   //   like a waste of time.
138   string data;
139 
140   {
141     // Set up.
142     protobuf_unittest::TestAllTypes message;
143     TestUtil::SetAllFields(&message);
144     message.SerializeToString(&data);
145   }
146 
147   {
148     // Test ParseFromString.
149     protobuf_unittest::TestAllTypes message;
150     EXPECT_TRUE(message.ParseFromString(data));
151     TestUtil::ExpectAllFieldsSet(message);
152   }
153 
154   {
155     // Test ParseFromIstream.
156     protobuf_unittest::TestAllTypes message;
157     stringstream stream(data);
158     EXPECT_TRUE(message.ParseFromIstream(&stream));
159     EXPECT_TRUE(stream.eof());
160     TestUtil::ExpectAllFieldsSet(message);
161   }
162 
163   {
164     // Test ParseFromBoundedZeroCopyStream.
165     string data_with_junk(data);
166     data_with_junk.append("some junk on the end");
167     io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
168     protobuf_unittest::TestAllTypes message;
169     EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
170     TestUtil::ExpectAllFieldsSet(message);
171   }
172 
173   {
174     // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
175     // EOF is reached before the expected number of bytes.
176     io::ArrayInputStream stream(data.data(), data.size());
177     protobuf_unittest::TestAllTypes message;
178     EXPECT_FALSE(
179       message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
180   }
181 }
182 
TEST(MessageTest,ParseFailsIfNotInitialized)183 TEST(MessageTest, ParseFailsIfNotInitialized) {
184   unittest::TestRequired message;
185   vector<string> errors;
186 
187   {
188     ScopedMemoryLog log;
189     EXPECT_FALSE(message.ParseFromString(""));
190     errors = log.GetMessages(ERROR);
191   }
192 
193   ASSERT_EQ(1, errors.size());
194   EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
195             "because it is missing required fields: a, b, c",
196             errors[0]);
197 }
198 
TEST(MessageTest,BypassInitializationCheckOnParse)199 TEST(MessageTest, BypassInitializationCheckOnParse) {
200   unittest::TestRequired message;
201   io::ArrayInputStream raw_input(NULL, 0);
202   io::CodedInputStream input(&raw_input);
203   EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
204 }
205 
TEST(MessageTest,InitializationErrorString)206 TEST(MessageTest, InitializationErrorString) {
207   unittest::TestRequired message;
208   EXPECT_EQ("a, b, c", message.InitializationErrorString());
209 }
210 
TEST(MessageTest,DynamicCastToGenerated)211 TEST(MessageTest, DynamicCastToGenerated) {
212   unittest::TestAllTypes test_all_types;
213 
214   google::protobuf::Message* test_all_types_pointer = &test_all_types;
215   EXPECT_EQ(&test_all_types,
216             google::protobuf::internal::DynamicCastToGenerated<unittest::TestAllTypes>(
217                 test_all_types_pointer));
218   EXPECT_EQ(NULL,
219             google::protobuf::internal::DynamicCastToGenerated<unittest::TestRequired>(
220                 test_all_types_pointer));
221 
222   const google::protobuf::Message* test_all_types_pointer_const = &test_all_types;
223   EXPECT_EQ(
224       &test_all_types,
225       google::protobuf::internal::DynamicCastToGenerated<const unittest::TestAllTypes>(
226           test_all_types_pointer_const));
227   EXPECT_EQ(
228       NULL,
229       google::protobuf::internal::DynamicCastToGenerated<const unittest::TestRequired>(
230           test_all_types_pointer_const));
231 }
232 
233 #ifdef PROTOBUF_HAS_DEATH_TEST  // death tests do not work on Windows yet.
234 
TEST(MessageTest,SerializeFailsIfNotInitialized)235 TEST(MessageTest, SerializeFailsIfNotInitialized) {
236   unittest::TestRequired message;
237   string data;
238   EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
239     "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
240     "it is missing required fields: a, b, c");
241 }
242 
TEST(MessageTest,CheckInitialized)243 TEST(MessageTest, CheckInitialized) {
244   unittest::TestRequired message;
245   EXPECT_DEATH(message.CheckInitialized(),
246     "Message of type \"protobuf_unittest.TestRequired\" is missing required "
247     "fields: a, b, c");
248 }
249 
TEST(MessageTest,CheckOverflow)250 TEST(MessageTest, CheckOverflow) {
251   unittest::TestAllTypes message;
252   // Create a message with size just over 2GB. This triggers integer overflow
253   // when computing message size.
254   const string data(1024, 'x');
255   Cord one_megabyte;
256   for (int i = 0; i < 1024; i++) {
257     one_megabyte.Append(data);
258   }
259 
260   for (int i = 0; i < 2 * 1024 + 1; ++i) {
261     message.add_repeated_cord()->CopyFrom(one_megabyte);
262   }
263 
264   Cord serialized;
265   EXPECT_FALSE(message.AppendToCord(&serialized));
266 }
267 
268 #endif  // PROTOBUF_HAS_DEATH_TEST
269 
270 namespace {
271 
272 class NegativeByteSize : public unittest::TestRequired {
273  public:
ByteSize() const274   virtual int ByteSize() const { return -1; }
275 };
276 
277 }  // namespace
278 
TEST(MessageTest,SerializationFailsOnNegativeByteSize)279 TEST(MessageTest, SerializationFailsOnNegativeByteSize) {
280   NegativeByteSize message;
281   string string_output;
282   EXPECT_FALSE(message.AppendPartialToString(&string_output));
283 
284   io::ArrayOutputStream coded_raw_output(NULL, 100);
285   io::CodedOutputStream coded_output(&coded_raw_output);
286   EXPECT_FALSE(message.SerializePartialToCodedStream(&coded_output));
287 }
288 
TEST(MessageTest,BypassInitializationCheckOnSerialize)289 TEST(MessageTest, BypassInitializationCheckOnSerialize) {
290   unittest::TestRequired message;
291   io::ArrayOutputStream raw_output(NULL, 0);
292   io::CodedOutputStream output(&raw_output);
293   EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
294 }
295 
TEST(MessageTest,FindInitializationErrors)296 TEST(MessageTest, FindInitializationErrors) {
297   unittest::TestRequired message;
298   vector<string> errors;
299   message.FindInitializationErrors(&errors);
300   ASSERT_EQ(3, errors.size());
301   EXPECT_EQ("a", errors[0]);
302   EXPECT_EQ("b", errors[1]);
303   EXPECT_EQ("c", errors[2]);
304 }
305 
TEST(MessageTest,ParseFailsOnInvalidMessageEnd)306 TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
307   unittest::TestAllTypes message;
308 
309   // Control case.
310   EXPECT_TRUE(message.ParseFromArray("", 0));
311 
312   // The byte is a valid varint, but not a valid tag (zero).
313   EXPECT_FALSE(message.ParseFromArray("\0", 1));
314 
315   // The byte is a malformed varint.
316   EXPECT_FALSE(message.ParseFromArray("\200", 1));
317 
318   // The byte is an endgroup tag, but we aren't parsing a group.
319   EXPECT_FALSE(message.ParseFromArray("\014", 1));
320 }
321 
322 namespace {
323 
ExpectMessageMerged(const unittest::TestAllTypes & message)324 void ExpectMessageMerged(const unittest::TestAllTypes& message) {
325   EXPECT_EQ(3, message.optional_int32());
326   EXPECT_EQ(2, message.optional_int64());
327   EXPECT_EQ("hello", message.optional_string());
328 }
329 
AssignParsingMergeMessages(unittest::TestAllTypes * msg1,unittest::TestAllTypes * msg2,unittest::TestAllTypes * msg3)330 void AssignParsingMergeMessages(
331     unittest::TestAllTypes* msg1,
332     unittest::TestAllTypes* msg2,
333     unittest::TestAllTypes* msg3) {
334   msg1->set_optional_int32(1);
335   msg2->set_optional_int64(2);
336   msg3->set_optional_int32(3);
337   msg3->set_optional_string("hello");
338 }
339 
340 }  // namespace
341 
342 // Test that if an optional or required message/group field appears multiple
343 // times in the input, they need to be merged.
TEST(MessageTest,ParsingMerge)344 TEST(MessageTest, ParsingMerge) {
345   unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
346   unittest::TestAllTypes* msg1;
347   unittest::TestAllTypes* msg2;
348   unittest::TestAllTypes* msg3;
349 
350 #define ASSIGN_REPEATED_FIELD(FIELD)                \
351   msg1 = generator.add_##FIELD();                   \
352   msg2 = generator.add_##FIELD();                   \
353   msg3 = generator.add_##FIELD();                   \
354   AssignParsingMergeMessages(msg1, msg2, msg3)
355 
356   ASSIGN_REPEATED_FIELD(field1);
357   ASSIGN_REPEATED_FIELD(field2);
358   ASSIGN_REPEATED_FIELD(field3);
359   ASSIGN_REPEATED_FIELD(ext1);
360   ASSIGN_REPEATED_FIELD(ext2);
361 
362 #undef ASSIGN_REPEATED_FIELD
363 #define ASSIGN_REPEATED_GROUP(FIELD)                \
364   msg1 = generator.add_##FIELD()->mutable_field1(); \
365   msg2 = generator.add_##FIELD()->mutable_field1(); \
366   msg3 = generator.add_##FIELD()->mutable_field1(); \
367   AssignParsingMergeMessages(msg1, msg2, msg3)
368 
369   ASSIGN_REPEATED_GROUP(group1);
370   ASSIGN_REPEATED_GROUP(group2);
371 
372 #undef ASSIGN_REPEATED_GROUP
373 
374   string buffer;
375   generator.SerializeToString(&buffer);
376   unittest::TestParsingMerge parsing_merge;
377   parsing_merge.ParseFromString(buffer);
378 
379   // Required and optional fields should be merged.
380   ExpectMessageMerged(parsing_merge.required_all_types());
381   ExpectMessageMerged(parsing_merge.optional_all_types());
382   ExpectMessageMerged(
383       parsing_merge.optionalgroup().optional_group_all_types());
384   ExpectMessageMerged(
385       parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
386 
387   // Repeated fields should not be merged.
388   EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
389   EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
390   EXPECT_EQ(3, parsing_merge.ExtensionSize(
391       unittest::TestParsingMerge::repeated_ext));
392 }
393 
TEST(MessageTest,MergeFrom)394 TEST(MessageTest, MergeFrom) {
395   unittest::TestAllTypes source;
396   unittest::TestAllTypes dest;
397 
398   // Optional fields
399   source.set_optional_int32(1);  // only source
400   source.set_optional_int64(2);  // both source and dest
401   dest.set_optional_int64(3);
402   dest.set_optional_uint32(4);   // only dest
403 
404   // Optional fields with defaults
405   source.set_default_int32(13);  // only source
406   source.set_default_int64(14);  // both source and dest
407   dest.set_default_int64(15);
408   dest.set_default_uint32(16);   // only dest
409 
410   // Repeated fields
411   source.add_repeated_int32(5);  // only source
412   source.add_repeated_int32(6);
413   source.add_repeated_int64(7);  // both source and dest
414   source.add_repeated_int64(8);
415   dest.add_repeated_int64(9);
416   dest.add_repeated_int64(10);
417   dest.add_repeated_uint32(11);  // only dest
418   dest.add_repeated_uint32(12);
419 
420   dest.MergeFrom(source);
421 
422   // Optional fields: source overwrites dest if source is specified
423   EXPECT_EQ(1, dest.optional_int32());  // only source: use source
424   EXPECT_EQ(2, dest.optional_int64());  // source and dest: use source
425   EXPECT_EQ(4, dest.optional_uint32());  // only dest: use dest
426   EXPECT_EQ(0, dest.optional_uint64());  // neither: use default
427 
428   // Optional fields with defaults
429   EXPECT_EQ(13, dest.default_int32());  // only source: use source
430   EXPECT_EQ(14, dest.default_int64());  // source and dest: use source
431   EXPECT_EQ(16, dest.default_uint32());  // only dest: use dest
432   EXPECT_EQ(44, dest.default_uint64());  // neither: use default
433 
434   // Repeated fields: concatenate source onto the end of dest
435   ASSERT_EQ(2, dest.repeated_int32_size());
436   EXPECT_EQ(5, dest.repeated_int32(0));
437   EXPECT_EQ(6, dest.repeated_int32(1));
438   ASSERT_EQ(4, dest.repeated_int64_size());
439   EXPECT_EQ(9,  dest.repeated_int64(0));
440   EXPECT_EQ(10, dest.repeated_int64(1));
441   EXPECT_EQ(7,  dest.repeated_int64(2));
442   EXPECT_EQ(8,  dest.repeated_int64(3));
443   ASSERT_EQ(2, dest.repeated_uint32_size());
444   EXPECT_EQ(11, dest.repeated_uint32(0));
445   EXPECT_EQ(12, dest.repeated_uint32(1));
446   ASSERT_EQ(0, dest.repeated_uint64_size());
447 }
448 
TEST(MessageFactoryTest,GeneratedFactoryLookup)449 TEST(MessageFactoryTest, GeneratedFactoryLookup) {
450   EXPECT_EQ(
451     MessageFactory::generated_factory()->GetPrototype(
452       protobuf_unittest::TestAllTypes::descriptor()),
453     &protobuf_unittest::TestAllTypes::default_instance());
454 }
455 
TEST(MessageFactoryTest,GeneratedFactoryUnknownType)456 TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
457   // Construct a new descriptor.
458   DescriptorPool pool;
459   FileDescriptorProto file;
460   file.set_name("foo.proto");
461   file.add_message_type()->set_name("Foo");
462   const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
463 
464   // Trying to construct it should return NULL.
465   EXPECT_TRUE(
466     MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
467 }
468 
469 
470 }  // namespace protobuf
471 }  // namespace google
472