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