blob: 6ffdcce09a967cdf2a9f8edafb785349bc3677d4 [file] [log] [blame]
Austin Schuh40c16522018-10-28 20:27:54 -07001// 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// This file needs to be included as .inc as it depends on certain macros being
36// defined prior to its inclusion.
37
38#include <google/protobuf/message.h>
39
40#include <fcntl.h>
41#include <sys/stat.h>
42#include <sys/types.h>
43#ifndef _MSC_VER
44#include <unistd.h>
45#endif
46#include <fstream>
47#include <sstream>
48
49#include <google/protobuf/io/coded_stream.h>
50#include <google/protobuf/io/zero_copy_stream.h>
51#include <google/protobuf/io/zero_copy_stream_impl.h>
52#include <google/protobuf/descriptor.pb.h>
53#include <google/protobuf/arena.h>
54#include <google/protobuf/descriptor.h>
55#include <google/protobuf/generated_message_reflection.h>
56
57#include <google/protobuf/stubs/logging.h>
58#include <google/protobuf/stubs/common.h>
59#include <google/protobuf/stubs/logging.h>
60#include <google/protobuf/testing/googletest.h>
61#include <gtest/gtest.h>
62#include <google/protobuf/stubs/io_win32.h>
63
64namespace google {
65namespace protobuf {
66
67#if defined(_WIN32)
68// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
69// them like we do below.
70using google::protobuf::internal::win32::close;
71using google::protobuf::internal::win32::open;
72#endif
73
74#ifndef O_BINARY
75#ifdef _O_BINARY
76#define O_BINARY _O_BINARY
77#else
78#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
79#endif
80#endif
81
82TEST(MESSAGE_TEST_NAME, SerializeHelpers) {
83 // TODO(kenton): Test more helpers? They're all two-liners so it seems
84 // like a waste of time.
85
86 UNITTEST::TestAllTypes message;
87 TestUtil::SetAllFields(&message);
88 std::stringstream stream;
89
90 string str1("foo");
91 string str2("bar");
92
93 EXPECT_TRUE(message.SerializeToString(&str1));
94 EXPECT_TRUE(message.AppendToString(&str2));
95 EXPECT_TRUE(message.SerializeToOstream(&stream));
96
97 EXPECT_EQ(str1.size() + 3, str2.size());
98 EXPECT_EQ("bar", str2.substr(0, 3));
99 // Don't use EXPECT_EQ because we don't want to dump raw binary data to
100 // stdout.
101 EXPECT_TRUE(str2.substr(3) == str1);
102
103 // GCC gives some sort of error if we try to just do stream.str() == str1.
104 string temp = stream.str();
105 EXPECT_TRUE(temp == str1);
106
107 EXPECT_TRUE(message.SerializeAsString() == str1);
108
109}
110
111TEST(MESSAGE_TEST_NAME, SerializeToBrokenOstream) {
112 std::ofstream out;
113 UNITTEST::TestAllTypes message;
114 message.set_optional_int32(123);
115
116 EXPECT_FALSE(message.SerializeToOstream(&out));
117}
118
119TEST(MESSAGE_TEST_NAME, ParseFromFileDescriptor) {
120 string filename = TestSourceDir() +
121 "/google/protobuf/testdata/golden_message";
122 int file = open(filename.c_str(), O_RDONLY | O_BINARY);
123 ASSERT_GE(file, 0);
124
125 UNITTEST::TestAllTypes message;
126 EXPECT_TRUE(message.ParseFromFileDescriptor(file));
127 TestUtil::ExpectAllFieldsSet(message);
128
129 EXPECT_GE(close(file), 0);
130}
131
132TEST(MESSAGE_TEST_NAME, ParsePackedFromFileDescriptor) {
133 string filename =
134 TestSourceDir() +
135 "/google/protobuf/testdata/golden_packed_fields_message";
136 int file = open(filename.c_str(), O_RDONLY | O_BINARY);
137 ASSERT_GE(file, 0);
138
139 UNITTEST::TestPackedTypes message;
140 EXPECT_TRUE(message.ParseFromFileDescriptor(file));
141 TestUtil::ExpectPackedFieldsSet(message);
142
143 EXPECT_GE(close(file), 0);
144}
145
146TEST(MESSAGE_TEST_NAME, ParseHelpers) {
147 // TODO(kenton): Test more helpers? They're all two-liners so it seems
148 // like a waste of time.
149 string data;
150
151 {
152 // Set up.
153 UNITTEST::TestAllTypes message;
154 TestUtil::SetAllFields(&message);
155 message.SerializeToString(&data);
156 }
157
158 {
159 // Test ParseFromString.
160 UNITTEST::TestAllTypes message;
161 EXPECT_TRUE(message.ParseFromString(data));
162 TestUtil::ExpectAllFieldsSet(message);
163 }
164
165 {
166 // Test ParseFromIstream.
167 UNITTEST::TestAllTypes message;
168 std::stringstream stream(data);
169 EXPECT_TRUE(message.ParseFromIstream(&stream));
170 EXPECT_TRUE(stream.eof());
171 TestUtil::ExpectAllFieldsSet(message);
172 }
173
174 {
175 // Test ParseFromBoundedZeroCopyStream.
176 string data_with_junk(data);
177 data_with_junk.append("some junk on the end");
178 io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
179 UNITTEST::TestAllTypes message;
180 EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
181 TestUtil::ExpectAllFieldsSet(message);
182 }
183
184 {
185 // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
186 // EOF is reached before the expected number of bytes.
187 io::ArrayInputStream stream(data.data(), data.size());
188 UNITTEST::TestAllTypes message;
189 EXPECT_FALSE(
190 message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
191 }
192}
193
194TEST(MESSAGE_TEST_NAME, ParseFailsIfNotInitialized) {
195 UNITTEST::TestRequired message;
196 std::vector<string> errors;
197
198 {
199 ScopedMemoryLog log;
200 EXPECT_FALSE(message.ParseFromString(""));
201 errors = log.GetMessages(ERROR);
202 }
203
204 ASSERT_EQ(1, errors.size());
205 EXPECT_EQ(
206 "Can't parse message of type \"" + string(UNITTEST_PACKAGE_NAME) +
207 ".TestRequired\" because it is missing required fields: a, b, c",
208 errors[0]);
209}
210
211TEST(MESSAGE_TEST_NAME, BypassInitializationCheckOnParse) {
212 UNITTEST::TestRequired message;
213 io::ArrayInputStream raw_input(nullptr, 0);
214 io::CodedInputStream input(&raw_input);
215 EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
216}
217
218TEST(MESSAGE_TEST_NAME, InitializationErrorString) {
219 UNITTEST::TestRequired message;
220 EXPECT_EQ("a, b, c", message.InitializationErrorString());
221}
222
223TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) {
224 UNITTEST::TestAllTypes test_all_types;
225
226 google::protobuf::Message* test_all_types_pointer = &test_all_types;
227 EXPECT_EQ(&test_all_types,
228 google::protobuf::internal::DynamicCastToGenerated<UNITTEST::TestAllTypes>(
229 test_all_types_pointer));
230 EXPECT_EQ(nullptr,
231 google::protobuf::internal::DynamicCastToGenerated<UNITTEST::TestRequired>(
232 test_all_types_pointer));
233
234 const google::protobuf::Message* test_all_types_pointer_const = &test_all_types;
235 EXPECT_EQ(
236 &test_all_types,
237 google::protobuf::internal::DynamicCastToGenerated<const UNITTEST::TestAllTypes>(
238 test_all_types_pointer_const));
239 EXPECT_EQ(
240 nullptr,
241 google::protobuf::internal::DynamicCastToGenerated<const UNITTEST::TestRequired>(
242 test_all_types_pointer_const));
243}
244
245#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet.
246
247TEST(MESSAGE_TEST_NAME, SerializeFailsIfNotInitialized) {
248 UNITTEST::TestRequired message;
249 string data;
250 EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
251 "Can't serialize message of type \"" +
252 string(UNITTEST_PACKAGE_NAME) +
253 ".TestRequired\" because "
254 "it is missing required fields: a, b, c");
255}
256
257TEST(MESSAGE_TEST_NAME, CheckInitialized) {
258 UNITTEST::TestRequired message;
259 EXPECT_DEATH(message.CheckInitialized(),
260 "Message of type \"" +
261 string(UNITTEST_PACKAGE_NAME) +
262 ".TestRequired\" is missing required "
263 "fields: a, b, c");
264}
265
266#endif // PROTOBUF_HAS_DEATH_TEST
267
268namespace {
269// An input stream that repeats a string's content for a number of times. It
270// helps us create a really large input without consuming too much memory. Used
271// to test the parsing behavior when the input size exceeds 2G or close to it.
272class RepeatedInputStream : public io::ZeroCopyInputStream {
273 public:
274 RepeatedInputStream(const string& data, size_t count)
275 : data_(data), count_(count), position_(0), total_byte_count_(0) {}
276
277 virtual bool Next(const void** data, int* size) {
278 if (position_ == data_.size()) {
279 if (--count_ == 0) {
280 return false;
281 }
282 position_ = 0;
283 }
284 *data = &data_[position_];
285 *size = static_cast<int>(data_.size() - position_);
286 position_ = data_.size();
287 total_byte_count_ += *size;
288 return true;
289 }
290
291 virtual void BackUp(int count) {
292 position_ -= static_cast<size_t>(count);
293 total_byte_count_ -= count;
294 }
295
296 virtual bool Skip(int count) {
297 while (count > 0) {
298 const void* data;
299 int size;
300 if (!Next(&data, &size)) {
301 break;
302 }
303 if (size >= count) {
304 BackUp(size - count);
305 return true;
306 } else {
307 count -= size;
308 }
309 }
310 return false;
311 }
312
313 virtual int64 ByteCount() const { return total_byte_count_; }
314
315 private:
316 string data_;
317 size_t count_; // The number of strings that haven't been consuemd.
318 size_t position_; // Position in the string for the next read.
319 int64 total_byte_count_;
320};
321} // namespace
322
323TEST(MESSAGE_TEST_NAME, TestParseMessagesCloseTo2G) {
324 // Create a message with a large string field.
325 string value = string(64 * 1024 * 1024, 'x');
326 UNITTEST::TestAllTypes message;
327 message.set_optional_string(value);
328
329 // Repeat this message in the input stream to make the total input size
330 // close to 2G.
331 string data = message.SerializeAsString();
332 size_t count = static_cast<size_t>(kint32max) / data.size();
333 RepeatedInputStream input(data, count);
334
335 // The parsing should succeed.
336 UNITTEST::TestAllTypes result;
337 EXPECT_TRUE(result.ParseFromZeroCopyStream(&input));
338
339 // When there are multiple occurences of a singulr field, the last one
340 // should win.
341 EXPECT_EQ(value, result.optional_string());
342}
343
344TEST(MESSAGE_TEST_NAME, TestParseMessagesOver2G) {
345 // Create a message with a large string field.
346 string value = string(64 * 1024 * 1024, 'x');
347 UNITTEST::TestAllTypes message;
348 message.set_optional_string(value);
349
350 // Repeat this message in the input stream to make the total input size
351 // larger than 2G.
352 string data = message.SerializeAsString();
353 size_t count = static_cast<size_t>(kint32max) / data.size() + 1;
354 RepeatedInputStream input(data, count);
355
356 // The parsing should fail.
357 UNITTEST::TestAllTypes result;
358 EXPECT_FALSE(result.ParseFromZeroCopyStream(&input));
359}
360
361TEST(MESSAGE_TEST_NAME, BypassInitializationCheckOnSerialize) {
362 UNITTEST::TestRequired message;
363 io::ArrayOutputStream raw_output(nullptr, 0);
364 io::CodedOutputStream output(&raw_output);
365 EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
366}
367
368TEST(MESSAGE_TEST_NAME, FindInitializationErrors) {
369 UNITTEST::TestRequired message;
370 std::vector<string> errors;
371 message.FindInitializationErrors(&errors);
372 ASSERT_EQ(3, errors.size());
373 EXPECT_EQ("a", errors[0]);
374 EXPECT_EQ("b", errors[1]);
375 EXPECT_EQ("c", errors[2]);
376}
377
378TEST(MESSAGE_TEST_NAME, ParseFailsOnInvalidMessageEnd) {
379 UNITTEST::TestAllTypes message;
380
381 // Control case.
382 EXPECT_TRUE(message.ParseFromArray("", 0));
383
384 // The byte is a valid varint, but not a valid tag (zero).
385 EXPECT_FALSE(message.ParseFromArray("\0", 1));
386
387 // The byte is a malformed varint.
388 EXPECT_FALSE(message.ParseFromArray("\200", 1));
389
390 // The byte is an endgroup tag, but we aren't parsing a group.
391 EXPECT_FALSE(message.ParseFromArray("\014", 1));
392}
393
394// Regression test for b/23630858
395TEST(MESSAGE_TEST_NAME, MessageIsStillValidAfterParseFails) {
396 UNITTEST::TestAllTypes message;
397
398 // 9 0xFFs for the "optional_uint64" field.
399 string invalid_data = "\x20\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
400
401 EXPECT_FALSE(message.ParseFromString(invalid_data));
402 message.Clear();
403 EXPECT_EQ(0, message.optional_uint64());
404
405 // invalid data for field "optional_string". Length prefix is 1 but no
406 // payload.
407 string invalid_string_data = "\x72\x01";
408 {
409 google::protobuf::Arena arena;
410 UNITTEST::TestAllTypes* arena_message =
411 google::protobuf::Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena);
412 EXPECT_FALSE(arena_message->ParseFromString(invalid_string_data));
413 arena_message->Clear();
414 EXPECT_EQ("", arena_message->optional_string());
415 }
416}
417
418
419namespace {
420
421void ExpectMessageMerged(const UNITTEST::TestAllTypes& message) {
422 EXPECT_EQ(3, message.optional_int32());
423 EXPECT_EQ(2, message.optional_int64());
424 EXPECT_EQ("hello", message.optional_string());
425}
426
427void AssignParsingMergeMessages(UNITTEST::TestAllTypes* msg1,
428 UNITTEST::TestAllTypes* msg2,
429 UNITTEST::TestAllTypes* msg3) {
430 msg1->set_optional_int32(1);
431 msg2->set_optional_int64(2);
432 msg3->set_optional_int32(3);
433 msg3->set_optional_string("hello");
434}
435
436} // namespace
437
438// Test that if an optional or required message/group field appears multiple
439// times in the input, they need to be merged.
440TEST(MESSAGE_TEST_NAME, ParsingMerge) {
441 UNITTEST::TestParsingMerge::RepeatedFieldsGenerator generator;
442 UNITTEST::TestAllTypes* msg1;
443 UNITTEST::TestAllTypes* msg2;
444 UNITTEST::TestAllTypes* msg3;
445
446#define ASSIGN_REPEATED_FIELD(FIELD) \
447 msg1 = generator.add_##FIELD(); \
448 msg2 = generator.add_##FIELD(); \
449 msg3 = generator.add_##FIELD(); \
450 AssignParsingMergeMessages(msg1, msg2, msg3)
451
452 ASSIGN_REPEATED_FIELD(field1);
453 ASSIGN_REPEATED_FIELD(field2);
454 ASSIGN_REPEATED_FIELD(field3);
455 ASSIGN_REPEATED_FIELD(ext1);
456 ASSIGN_REPEATED_FIELD(ext2);
457
458#undef ASSIGN_REPEATED_FIELD
459#define ASSIGN_REPEATED_GROUP(FIELD) \
460 msg1 = generator.add_##FIELD()->mutable_field1(); \
461 msg2 = generator.add_##FIELD()->mutable_field1(); \
462 msg3 = generator.add_##FIELD()->mutable_field1(); \
463 AssignParsingMergeMessages(msg1, msg2, msg3)
464
465 ASSIGN_REPEATED_GROUP(group1);
466 ASSIGN_REPEATED_GROUP(group2);
467
468#undef ASSIGN_REPEATED_GROUP
469
470 string buffer;
471 generator.SerializeToString(&buffer);
472 UNITTEST::TestParsingMerge parsing_merge;
473 parsing_merge.ParseFromString(buffer);
474
475 // Required and optional fields should be merged.
476 ExpectMessageMerged(parsing_merge.required_all_types());
477 ExpectMessageMerged(parsing_merge.optional_all_types());
478 ExpectMessageMerged(parsing_merge.optionalgroup().optional_group_all_types());
479 ExpectMessageMerged(
480 parsing_merge.GetExtension(UNITTEST::TestParsingMerge::optional_ext));
481
482 // Repeated fields should not be merged.
483 EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
484 EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
485 EXPECT_EQ(
486 3, parsing_merge.ExtensionSize(UNITTEST::TestParsingMerge::repeated_ext));
487}
488
489TEST(MESSAGE_TEST_NAME, MergeFrom) {
490 UNITTEST::TestAllTypes source, dest;
491
492 // Optional fields
493 source.set_optional_int32(1); // only source
494 source.set_optional_int64(2); // both source and dest
495 dest.set_optional_int64(3);
496 dest.set_optional_uint32(4); // only dest
497
498 // Optional fields with defaults
499 source.set_default_int32(13); // only source
500 source.set_default_int64(14); // both source and dest
501 dest.set_default_int64(15);
502 dest.set_default_uint32(16); // only dest
503
504 // Repeated fields
505 source.add_repeated_int32(5); // only source
506 source.add_repeated_int32(6);
507 source.add_repeated_int64(7); // both source and dest
508 source.add_repeated_int64(8);
509 dest.add_repeated_int64(9);
510 dest.add_repeated_int64(10);
511 dest.add_repeated_uint32(11); // only dest
512 dest.add_repeated_uint32(12);
513
514 dest.MergeFrom(source);
515
516 // Optional fields: source overwrites dest if source is specified
517 EXPECT_EQ(1, dest.optional_int32()); // only source: use source
518 EXPECT_EQ(2, dest.optional_int64()); // source and dest: use source
519 EXPECT_EQ(4, dest.optional_uint32()); // only dest: use dest
520 EXPECT_EQ(0, dest.optional_uint64()); // neither: use default
521
522 // Optional fields with defaults
523 EXPECT_EQ(13, dest.default_int32()); // only source: use source
524 EXPECT_EQ(14, dest.default_int64()); // source and dest: use source
525 EXPECT_EQ(16, dest.default_uint32()); // only dest: use dest
526 EXPECT_EQ(44, dest.default_uint64()); // neither: use default
527
528 // Repeated fields: concatenate source onto the end of dest
529 ASSERT_EQ(2, dest.repeated_int32_size());
530 EXPECT_EQ(5, dest.repeated_int32(0));
531 EXPECT_EQ(6, dest.repeated_int32(1));
532 ASSERT_EQ(4, dest.repeated_int64_size());
533 EXPECT_EQ(9, dest.repeated_int64(0));
534 EXPECT_EQ(10, dest.repeated_int64(1));
535 EXPECT_EQ(7, dest.repeated_int64(2));
536 EXPECT_EQ(8, dest.repeated_int64(3));
537 ASSERT_EQ(2, dest.repeated_uint32_size());
538 EXPECT_EQ(11, dest.repeated_uint32(0));
539 EXPECT_EQ(12, dest.repeated_uint32(1));
540 ASSERT_EQ(0, dest.repeated_uint64_size());
541}
542
543TEST(MESSAGE_TEST_NAME, IsInitialized) {
544 UNITTEST::TestIsInitialized msg;
545 EXPECT_TRUE(msg.IsInitialized());
546 UNITTEST::TestIsInitialized::SubMessage* sub_message =
547 msg.mutable_sub_message();
548 EXPECT_TRUE(msg.IsInitialized());
549 UNITTEST::TestIsInitialized::SubMessage::SubGroup* sub_group =
550 sub_message->mutable_subgroup();
551 EXPECT_FALSE(msg.IsInitialized());
552 sub_group->set_i(1);
553 EXPECT_TRUE(msg.IsInitialized());
554}
555
556TEST(MESSAGE_FACTORY_TEST_NAME, GeneratedFactoryLookup) {
557 EXPECT_EQ(MessageFactory::generated_factory()->GetPrototype(
558 UNITTEST::TestAllTypes::descriptor()),
559 &UNITTEST::TestAllTypes::default_instance());
560}
561
562TEST(MESSAGE_FACTORY_TEST_NAME, GeneratedFactoryUnknownType) {
563 // Construct a new descriptor.
564 DescriptorPool pool;
565 FileDescriptorProto file;
566 file.set_name("foo.proto");
567 file.add_message_type()->set_name("Foo");
568 const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
569
570 // Trying to construct it should return nullptr.
571 EXPECT_TRUE(MessageFactory::generated_factory()->GetPrototype(descriptor) ==
572 nullptr);
573}
574
575
576} // namespace protobuf
577} // namespace google