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 
59 namespace google {
60 namespace 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 
TEST(MessageTest,SerializeHelpers)70 TEST(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 
TEST(MessageTest,SerializeToBrokenOstream)99 TEST(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 
TEST(MessageTest,ParseFromFileDescriptor)107 TEST(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 
TEST(MessageTest,ParsePackedFromFileDescriptor)119 TEST(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 
TEST(MessageTest,ParseHelpers)132 TEST(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 
TEST(MessageTest,ParseFailsIfNotInitialized)180 TEST(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 
TEST(MessageTest,BypassInitializationCheckOnParse)196 TEST(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 
TEST(MessageTest,InitializationErrorString)203 TEST(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 
TEST(MessageTest,SerializeFailsIfNotInitialized)210 TEST(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 
TEST(MessageTest,CheckInitialized)218 TEST(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 
TEST(MessageTest,CheckOverflow)225 TEST(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 
TEST(MessageTest,BypassInitializationCheckOnSerialize)245 TEST(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 
TEST(MessageTest,FindInitializationErrors)252 TEST(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 
TEST(MessageTest,ParseFailsOnInvalidMessageEnd)262 TEST(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 
278 namespace {
279 
ExpectMessageMerged(const unittest::TestAllTypes & message)280 void 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 
AssignParsingMergeMessages(unittest::TestAllTypes * msg1,unittest::TestAllTypes * msg2,unittest::TestAllTypes * msg3)286 void 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.
TEST(MessageTest,ParsingMerge)300 TEST(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 
TEST(MessageTest,MergeFrom)350 TEST(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 
TEST(MessageFactoryTest,GeneratedFactoryLookup)405 TEST(MessageFactoryTest, GeneratedFactoryLookup) {
406   EXPECT_EQ(
407     MessageFactory::generated_factory()->GetPrototype(
408       protobuf_unittest::TestAllTypes::descriptor()),
409     &protobuf_unittest::TestAllTypes::default_instance());
410 }
411 
TEST(MessageFactoryTest,GeneratedFactoryUnknownType)412 TEST(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