blob: 15c37556eb166daf5bf8f41f35a7cb08e34759da [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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/wire_format.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000036#include <google/protobuf/wire_format_lite_inl.h>
temporal40ee5512008-07-10 02:12:20 +000037#include <google/protobuf/descriptor.h>
38#include <google/protobuf/io/zero_copy_stream_impl.h>
39#include <google/protobuf/io/coded_stream.h>
40#include <google/protobuf/unittest.pb.h>
Bo Yang5db21732015-05-21 14:28:59 -070041#include <google/protobuf/unittest_proto3_arena.pb.h>
temporal40ee5512008-07-10 02:12:20 +000042#include <google/protobuf/unittest_mset.pb.h>
Feng Xiaoeee38b02015-08-22 18:25:48 -070043#include <google/protobuf/unittest_mset_wire_format.pb.h>
temporal40ee5512008-07-10 02:12:20 +000044#include <google/protobuf/test_util.h>
45
Feng Xiaoeee38b02015-08-22 18:25:48 -070046#include <google/protobuf/stubs/logging.h>
temporal40ee5512008-07-10 02:12:20 +000047#include <google/protobuf/stubs/common.h>
48#include <google/protobuf/testing/googletest.h>
49#include <gtest/gtest.h>
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000050#include <google/protobuf/stubs/stl_util.h>
temporal40ee5512008-07-10 02:12:20 +000051
52namespace google {
53namespace protobuf {
54namespace internal {
55namespace {
56
kenton@google.com80b1d622009-07-29 01:13:20 +000057TEST(WireFormatTest, EnumsInSync) {
58 // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
59 // FieldDescriptor::Type and FieldDescriptor::CppType.
60
61 EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
62 implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
63 EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
64 implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
65
66 for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
67 EXPECT_EQ(
68 implicit_cast<int>(FieldDescriptor::TypeToCppType(
69 static_cast<FieldDescriptor::Type>(i))),
70 implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
71 static_cast<WireFormatLite::FieldType>(i))));
72 }
73}
74
temporal40ee5512008-07-10 02:12:20 +000075TEST(WireFormatTest, MaxFieldNumber) {
76 // Make sure the max field number constant is accurate.
kenton@google.com80b1d622009-07-29 01:13:20 +000077 EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1,
temporal40ee5512008-07-10 02:12:20 +000078 FieldDescriptor::kMaxNumber);
79}
80
81TEST(WireFormatTest, Parse) {
82 unittest::TestAllTypes source, dest;
83 string data;
84
85 // Serialize using the generated code.
86 TestUtil::SetAllFields(&source);
87 source.SerializeToString(&data);
88
89 // Parse using WireFormat.
90 io::ArrayInputStream raw_input(data.data(), data.size());
91 io::CodedInputStream input(&raw_input);
temporal779f61c2008-08-13 03:15:00 +000092 WireFormat::ParseAndMergePartial(&input, &dest);
temporal40ee5512008-07-10 02:12:20 +000093
94 // Check.
95 TestUtil::ExpectAllFieldsSet(dest);
96}
97
98TEST(WireFormatTest, ParseExtensions) {
99 unittest::TestAllExtensions source, dest;
100 string data;
101
102 // Serialize using the generated code.
103 TestUtil::SetAllExtensions(&source);
104 source.SerializeToString(&data);
105
106 // Parse using WireFormat.
107 io::ArrayInputStream raw_input(data.data(), data.size());
108 io::CodedInputStream input(&raw_input);
temporal779f61c2008-08-13 03:15:00 +0000109 WireFormat::ParseAndMergePartial(&input, &dest);
temporal40ee5512008-07-10 02:12:20 +0000110
111 // Check.
112 TestUtil::ExpectAllExtensionsSet(dest);
113}
114
kenton@google.com2d6daa72009-01-22 01:27:00 +0000115TEST(WireFormatTest, ParsePacked) {
116 unittest::TestPackedTypes source, dest;
117 string data;
118
119 // Serialize using the generated code.
120 TestUtil::SetPackedFields(&source);
121 source.SerializeToString(&data);
122
123 // Parse using WireFormat.
124 io::ArrayInputStream raw_input(data.data(), data.size());
125 io::CodedInputStream input(&raw_input);
126 WireFormat::ParseAndMergePartial(&input, &dest);
127
128 // Check.
129 TestUtil::ExpectPackedFieldsSet(dest);
130}
131
kenton@google.comfccb1462009-12-18 02:11:36 +0000132TEST(WireFormatTest, ParsePackedFromUnpacked) {
133 // Serialize using the generated code.
134 unittest::TestUnpackedTypes source;
135 TestUtil::SetUnpackedFields(&source);
136 string data = source.SerializeAsString();
137
138 // Parse using WireFormat.
139 unittest::TestPackedTypes dest;
140 io::ArrayInputStream raw_input(data.data(), data.size());
141 io::CodedInputStream input(&raw_input);
142 WireFormat::ParseAndMergePartial(&input, &dest);
143
144 // Check.
145 TestUtil::ExpectPackedFieldsSet(dest);
146}
147
148TEST(WireFormatTest, ParseUnpackedFromPacked) {
149 // Serialize using the generated code.
150 unittest::TestPackedTypes source;
151 TestUtil::SetPackedFields(&source);
152 string data = source.SerializeAsString();
153
154 // Parse using WireFormat.
155 unittest::TestUnpackedTypes dest;
156 io::ArrayInputStream raw_input(data.data(), data.size());
157 io::CodedInputStream input(&raw_input);
158 WireFormat::ParseAndMergePartial(&input, &dest);
159
160 // Check.
161 TestUtil::ExpectUnpackedFieldsSet(dest);
162}
163
kenton@google.com2d6daa72009-01-22 01:27:00 +0000164TEST(WireFormatTest, ParsePackedExtensions) {
165 unittest::TestPackedExtensions source, dest;
166 string data;
167
168 // Serialize using the generated code.
169 TestUtil::SetPackedExtensions(&source);
170 source.SerializeToString(&data);
171
172 // Parse using WireFormat.
173 io::ArrayInputStream raw_input(data.data(), data.size());
174 io::CodedInputStream input(&raw_input);
175 WireFormat::ParseAndMergePartial(&input, &dest);
176
177 // Check.
178 TestUtil::ExpectPackedExtensionsSet(dest);
179}
180
jieluo@google.com4de8f552014-07-18 00:47:59 +0000181TEST(WireFormatTest, ParseOneof) {
182 unittest::TestOneof2 source, dest;
183 string data;
184
185 // Serialize using the generated code.
186 TestUtil::SetOneof1(&source);
187 source.SerializeToString(&data);
188
189 // Parse using WireFormat.
190 io::ArrayInputStream raw_input(data.data(), data.size());
191 io::CodedInputStream input(&raw_input);
192 WireFormat::ParseAndMergePartial(&input, &dest);
193
194 // Check.
195 TestUtil::ExpectOneofSet1(dest);
196}
197
198TEST(WireFormatTest, OneofOnlySetLast) {
199 unittest::TestOneofBackwardsCompatible source;
200 unittest::TestOneof oneof_dest;
201 string data;
202
203 // Set two fields
204 source.set_foo_int(100);
205 source.set_foo_string("101");
206
207 // Serialize and parse to oneof message.
208 source.SerializeToString(&data);
209 io::ArrayInputStream raw_input(data.data(), data.size());
210 io::CodedInputStream input(&raw_input);
211 WireFormat::ParseAndMergePartial(&input, &oneof_dest);
212
213 // Only the last field is set.
214 EXPECT_FALSE(oneof_dest.has_foo_int());
215 EXPECT_TRUE(oneof_dest.has_foo_string());
216}
217
temporal40ee5512008-07-10 02:12:20 +0000218TEST(WireFormatTest, ByteSize) {
219 unittest::TestAllTypes message;
220 TestUtil::SetAllFields(&message);
221
temporal779f61c2008-08-13 03:15:00 +0000222 EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000223 message.Clear();
224 EXPECT_EQ(0, message.ByteSize());
temporal779f61c2008-08-13 03:15:00 +0000225 EXPECT_EQ(0, WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000226}
227
228TEST(WireFormatTest, ByteSizeExtensions) {
229 unittest::TestAllExtensions message;
230 TestUtil::SetAllExtensions(&message);
231
232 EXPECT_EQ(message.ByteSize(),
temporal779f61c2008-08-13 03:15:00 +0000233 WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000234 message.Clear();
235 EXPECT_EQ(0, message.ByteSize());
temporal779f61c2008-08-13 03:15:00 +0000236 EXPECT_EQ(0, WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000237}
238
kenton@google.com2d6daa72009-01-22 01:27:00 +0000239TEST(WireFormatTest, ByteSizePacked) {
240 unittest::TestPackedTypes message;
241 TestUtil::SetPackedFields(&message);
242
243 EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
244 message.Clear();
245 EXPECT_EQ(0, message.ByteSize());
246 EXPECT_EQ(0, WireFormat::ByteSize(message));
247}
248
249TEST(WireFormatTest, ByteSizePackedExtensions) {
250 unittest::TestPackedExtensions message;
251 TestUtil::SetPackedExtensions(&message);
252
253 EXPECT_EQ(message.ByteSize(),
254 WireFormat::ByteSize(message));
255 message.Clear();
256 EXPECT_EQ(0, message.ByteSize());
257 EXPECT_EQ(0, WireFormat::ByteSize(message));
258}
259
jieluo@google.com4de8f552014-07-18 00:47:59 +0000260TEST(WireFormatTest, ByteSizeOneof) {
261 unittest::TestOneof2 message;
262 TestUtil::SetOneof1(&message);
263
264 EXPECT_EQ(message.ByteSize(),
265 WireFormat::ByteSize(message));
266 message.Clear();
267
268 EXPECT_EQ(0, message.ByteSize());
269 EXPECT_EQ(0, WireFormat::ByteSize(message));
270}
271
temporal40ee5512008-07-10 02:12:20 +0000272TEST(WireFormatTest, Serialize) {
273 unittest::TestAllTypes message;
274 string generated_data;
275 string dynamic_data;
276
277 TestUtil::SetAllFields(&message);
278 int size = message.ByteSize();
279
280 // Serialize using the generated code.
281 {
282 io::StringOutputStream raw_output(&generated_data);
283 io::CodedOutputStream output(&raw_output);
284 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000285 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000286 }
287
288 // Serialize using WireFormat.
289 {
290 io::StringOutputStream raw_output(&dynamic_data);
291 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000292 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000293 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000294 }
295
296 // Should be the same.
297 // Don't use EXPECT_EQ here because we're comparing raw binary data and
298 // we really don't want it dumped to stdout on failure.
299 EXPECT_TRUE(dynamic_data == generated_data);
300}
301
302TEST(WireFormatTest, SerializeExtensions) {
303 unittest::TestAllExtensions message;
304 string generated_data;
305 string dynamic_data;
306
307 TestUtil::SetAllExtensions(&message);
308 int size = message.ByteSize();
309
310 // Serialize using the generated code.
311 {
312 io::StringOutputStream raw_output(&generated_data);
313 io::CodedOutputStream output(&raw_output);
314 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000315 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000316 }
317
318 // Serialize using WireFormat.
319 {
320 io::StringOutputStream raw_output(&dynamic_data);
321 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000322 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000323 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000324 }
325
326 // Should be the same.
327 // Don't use EXPECT_EQ here because we're comparing raw binary data and
328 // we really don't want it dumped to stdout on failure.
329 EXPECT_TRUE(dynamic_data == generated_data);
330}
331
332TEST(WireFormatTest, SerializeFieldsAndExtensions) {
333 unittest::TestFieldOrderings message;
334 string generated_data;
335 string dynamic_data;
336
337 TestUtil::SetAllFieldsAndExtensions(&message);
338 int size = message.ByteSize();
339
340 // Serialize using the generated code.
341 {
342 io::StringOutputStream raw_output(&generated_data);
343 io::CodedOutputStream output(&raw_output);
344 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000345 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000346 }
347
348 // Serialize using WireFormat.
349 {
350 io::StringOutputStream raw_output(&dynamic_data);
351 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000352 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000353 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000354 }
355
356 // Should be the same.
357 // Don't use EXPECT_EQ here because we're comparing raw binary data and
358 // we really don't want it dumped to stdout on failure.
359 EXPECT_TRUE(dynamic_data == generated_data);
360
361 // Should output in canonical order.
362 TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data);
363 TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
364}
365
jieluo@google.com4de8f552014-07-18 00:47:59 +0000366TEST(WireFormatTest, SerializeOneof) {
367 unittest::TestOneof2 message;
368 string generated_data;
369 string dynamic_data;
370
371 TestUtil::SetOneof1(&message);
372 int size = message.ByteSize();
373
374 // Serialize using the generated code.
375 {
376 io::StringOutputStream raw_output(&generated_data);
377 io::CodedOutputStream output(&raw_output);
378 message.SerializeWithCachedSizes(&output);
379 ASSERT_FALSE(output.HadError());
380 }
381
382 // Serialize using WireFormat.
383 {
384 io::StringOutputStream raw_output(&dynamic_data);
385 io::CodedOutputStream output(&raw_output);
386 WireFormat::SerializeWithCachedSizes(message, size, &output);
387 ASSERT_FALSE(output.HadError());
388 }
389
390 // Should be the same.
391 // Don't use EXPECT_EQ here because we're comparing raw binary data and
392 // we really don't want it dumped to stdout on failure.
393 EXPECT_TRUE(dynamic_data == generated_data);
394}
395
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000396TEST(WireFormatTest, ParseMultipleExtensionRanges) {
397 // Make sure we can parse a message that contains multiple extensions ranges.
398 unittest::TestFieldOrderings source;
399 string data;
400
401 TestUtil::SetAllFieldsAndExtensions(&source);
402 source.SerializeToString(&data);
403
404 {
405 unittest::TestFieldOrderings dest;
406 EXPECT_TRUE(dest.ParseFromString(data));
407 EXPECT_EQ(source.DebugString(), dest.DebugString());
408 }
409
410 // Also test using reflection-based parsing.
411 {
412 unittest::TestFieldOrderings dest;
413 io::ArrayInputStream raw_input(data.data(), data.size());
414 io::CodedInputStream coded_input(&raw_input);
415 EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
416 EXPECT_EQ(source.DebugString(), dest.DebugString());
417 }
418}
419
temporal40ee5512008-07-10 02:12:20 +0000420const int kUnknownTypeId = 1550055;
421
422TEST(WireFormatTest, SerializeMessageSet) {
423 // Set up a TestMessageSet with two known messages and an unknown one.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700424 proto2_wireformat_unittest::TestMessageSet message_set;
temporal40ee5512008-07-10 02:12:20 +0000425 message_set.MutableExtension(
426 unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
427 message_set.MutableExtension(
428 unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000429 message_set.mutable_unknown_fields()->AddLengthDelimited(
430 kUnknownTypeId, "bar");
temporal40ee5512008-07-10 02:12:20 +0000431
432 string data;
433 ASSERT_TRUE(message_set.SerializeToString(&data));
434
435 // Parse back using RawMessageSet and check the contents.
436 unittest::RawMessageSet raw;
437 ASSERT_TRUE(raw.ParseFromString(data));
438
439 EXPECT_EQ(0, raw.unknown_fields().field_count());
440
441 ASSERT_EQ(3, raw.item_size());
442 EXPECT_EQ(
443 unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(),
444 raw.item(0).type_id());
445 EXPECT_EQ(
446 unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(),
447 raw.item(1).type_id());
448 EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
449
450 unittest::TestMessageSetExtension1 message1;
451 EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
452 EXPECT_EQ(123, message1.i());
453
454 unittest::TestMessageSetExtension2 message2;
455 EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
456 EXPECT_EQ("foo", message2.str());
457
458 EXPECT_EQ("bar", raw.item(2).message());
459}
460
kenton@google.com80b1d622009-07-29 01:13:20 +0000461TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
462 // Serialize a MessageSet to a stream and to a flat array using generated
463 // code, and also using WireFormat, and check that the results are equal.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000464 // Set up a TestMessageSet with two known messages and an unknown one, as
465 // above.
466
Feng Xiaoeee38b02015-08-22 18:25:48 -0700467 proto2_wireformat_unittest::TestMessageSet message_set;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000468 message_set.MutableExtension(
469 unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
470 message_set.MutableExtension(
471 unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
472 message_set.mutable_unknown_fields()->AddLengthDelimited(
473 kUnknownTypeId, "bar");
474
475 int size = message_set.ByteSize();
kenton@google.com80b1d622009-07-29 01:13:20 +0000476 EXPECT_EQ(size, message_set.GetCachedSize());
477 ASSERT_EQ(size, WireFormat::ByteSize(message_set));
478
kenton@google.comd37d46d2009-04-25 02:53:47 +0000479 string flat_data;
480 string stream_data;
kenton@google.com80b1d622009-07-29 01:13:20 +0000481 string dynamic_data;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000482 flat_data.resize(size);
483 stream_data.resize(size);
kenton@google.com80b1d622009-07-29 01:13:20 +0000484
kenton@google.comd37d46d2009-04-25 02:53:47 +0000485 // Serialize to flat array
486 {
487 uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
488 uint8* end = message_set.SerializeWithCachedSizesToArray(target);
489 EXPECT_EQ(size, end - target);
490 }
491
492 // Serialize to buffer
493 {
494 io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
495 io::CodedOutputStream output_stream(&array_stream);
496 message_set.SerializeWithCachedSizes(&output_stream);
497 ASSERT_FALSE(output_stream.HadError());
498 }
499
kenton@google.com80b1d622009-07-29 01:13:20 +0000500 // Serialize to buffer with WireFormat.
501 {
502 io::StringOutputStream string_stream(&dynamic_data);
503 io::CodedOutputStream output_stream(&string_stream);
504 WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
505 ASSERT_FALSE(output_stream.HadError());
506 }
507
kenton@google.comd37d46d2009-04-25 02:53:47 +0000508 EXPECT_TRUE(flat_data == stream_data);
kenton@google.com80b1d622009-07-29 01:13:20 +0000509 EXPECT_TRUE(flat_data == dynamic_data);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000510}
511
temporal40ee5512008-07-10 02:12:20 +0000512TEST(WireFormatTest, ParseMessageSet) {
513 // Set up a RawMessageSet with two known messages and an unknown one.
514 unittest::RawMessageSet raw;
515
516 {
517 unittest::RawMessageSet::Item* item = raw.add_item();
518 item->set_type_id(
519 unittest::TestMessageSetExtension1::descriptor()->extension(0)->number());
520 unittest::TestMessageSetExtension1 message;
521 message.set_i(123);
522 message.SerializeToString(item->mutable_message());
523 }
524
525 {
526 unittest::RawMessageSet::Item* item = raw.add_item();
527 item->set_type_id(
528 unittest::TestMessageSetExtension2::descriptor()->extension(0)->number());
529 unittest::TestMessageSetExtension2 message;
530 message.set_str("foo");
531 message.SerializeToString(item->mutable_message());
532 }
533
534 {
535 unittest::RawMessageSet::Item* item = raw.add_item();
536 item->set_type_id(kUnknownTypeId);
537 item->set_message("bar");
538 }
539
540 string data;
541 ASSERT_TRUE(raw.SerializeToString(&data));
542
543 // Parse as a TestMessageSet and check the contents.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700544 proto2_wireformat_unittest::TestMessageSet message_set;
temporal40ee5512008-07-10 02:12:20 +0000545 ASSERT_TRUE(message_set.ParseFromString(data));
546
547 EXPECT_EQ(123, message_set.GetExtension(
548 unittest::TestMessageSetExtension1::message_set_extension).i());
549 EXPECT_EQ("foo", message_set.GetExtension(
550 unittest::TestMessageSetExtension2::message_set_extension).str());
551
552 ASSERT_EQ(1, message_set.unknown_fields().field_count());
kenton@google.comd37d46d2009-04-25 02:53:47 +0000553 ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED,
554 message_set.unknown_fields().field(0).type());
555 EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
kenton@google.com80b1d622009-07-29 01:13:20 +0000556
557 // Also parse using WireFormat.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700558 proto2_wireformat_unittest::TestMessageSet dynamic_message_set;
kenton@google.com80b1d622009-07-29 01:13:20 +0000559 io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
560 data.size());
561 ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
562 EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
temporal40ee5512008-07-10 02:12:20 +0000563}
564
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000565TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
566 string data;
567 {
568 unittest::TestMessageSetExtension1 message;
569 message.set_i(123);
570 // Build a MessageSet manually with its message content put before its
571 // type_id.
572 io::StringOutputStream output_stream(&data);
573 io::CodedOutputStream coded_output(&output_stream);
574 coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
575 // Write the message content first.
576 WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
577 WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
578 &coded_output);
579 coded_output.WriteVarint32(message.ByteSize());
580 message.SerializeWithCachedSizes(&coded_output);
581 // Write the type id.
xiaofeng@google.comfcb8a502012-09-24 06:48:20 +0000582 uint32 type_id = message.GetDescriptor()->extension(0)->number();
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000583 WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
584 type_id, &coded_output);
585 coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
586 }
587 {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700588 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000589 ASSERT_TRUE(message_set.ParseFromString(data));
590
591 EXPECT_EQ(123, message_set.GetExtension(
592 unittest::TestMessageSetExtension1::message_set_extension).i());
593 }
594 {
595 // Test parse the message via Reflection.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700596 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000597 io::CodedInputStream input(
598 reinterpret_cast<const uint8*>(data.data()), data.size());
599 EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
600 EXPECT_TRUE(input.ConsumedEntireMessage());
601
602 EXPECT_EQ(123, message_set.GetExtension(
603 unittest::TestMessageSetExtension1::message_set_extension).i());
604 }
605}
606
607TEST(WireFormatTest, ParseBrokenMessageSet) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700608 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000609 string input("goodbye"); // Invalid wire format data.
610 EXPECT_FALSE(message_set.ParseFromString(input));
611}
612
temporal40ee5512008-07-10 02:12:20 +0000613TEST(WireFormatTest, RecursionLimit) {
614 unittest::TestRecursiveMessage message;
615 message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
616 string data;
617 message.SerializeToString(&data);
618
619 {
620 io::ArrayInputStream raw_input(data.data(), data.size());
621 io::CodedInputStream input(&raw_input);
622 input.SetRecursionLimit(4);
623 unittest::TestRecursiveMessage message2;
624 EXPECT_TRUE(message2.ParseFromCodedStream(&input));
625 }
626
627 {
628 io::ArrayInputStream raw_input(data.data(), data.size());
629 io::CodedInputStream input(&raw_input);
630 input.SetRecursionLimit(3);
631 unittest::TestRecursiveMessage message2;
632 EXPECT_FALSE(message2.ParseFromCodedStream(&input));
633 }
634}
635
636TEST(WireFormatTest, UnknownFieldRecursionLimit) {
637 unittest::TestEmptyMessage message;
638 message.mutable_unknown_fields()
kenton@google.comd37d46d2009-04-25 02:53:47 +0000639 ->AddGroup(1234)
640 ->AddGroup(1234)
641 ->AddGroup(1234)
642 ->AddGroup(1234)
643 ->AddVarint(1234, 123);
temporal40ee5512008-07-10 02:12:20 +0000644 string data;
645 message.SerializeToString(&data);
646
647 {
648 io::ArrayInputStream raw_input(data.data(), data.size());
649 io::CodedInputStream input(&raw_input);
650 input.SetRecursionLimit(4);
651 unittest::TestEmptyMessage message2;
652 EXPECT_TRUE(message2.ParseFromCodedStream(&input));
653 }
654
655 {
656 io::ArrayInputStream raw_input(data.data(), data.size());
657 io::CodedInputStream input(&raw_input);
658 input.SetRecursionLimit(3);
659 unittest::TestEmptyMessage message2;
660 EXPECT_FALSE(message2.ParseFromCodedStream(&input));
661 }
662}
663
664TEST(WireFormatTest, ZigZag) {
665// avoid line-wrapping
666#define LL(x) GOOGLE_LONGLONG(x)
667#define ULL(x) GOOGLE_ULONGLONG(x)
kenton@google.com80b1d622009-07-29 01:13:20 +0000668#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x)
669#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
670#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
671#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x)
temporal40ee5512008-07-10 02:12:20 +0000672
673 EXPECT_EQ(0u, ZigZagEncode32( 0));
674 EXPECT_EQ(1u, ZigZagEncode32(-1));
675 EXPECT_EQ(2u, ZigZagEncode32( 1));
676 EXPECT_EQ(3u, ZigZagEncode32(-2));
677 EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
678 EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
679 EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
680 EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
681
682 EXPECT_EQ( 0, ZigZagDecode32(0u));
683 EXPECT_EQ(-1, ZigZagDecode32(1u));
684 EXPECT_EQ( 1, ZigZagDecode32(2u));
685 EXPECT_EQ(-2, ZigZagDecode32(3u));
686 EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
687 EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
688 EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
689 EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
690
691 EXPECT_EQ(0u, ZigZagEncode64( 0));
692 EXPECT_EQ(1u, ZigZagEncode64(-1));
693 EXPECT_EQ(2u, ZigZagEncode64( 1));
694 EXPECT_EQ(3u, ZigZagEncode64(-2));
695 EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
696 EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
697 EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
698 EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
699 EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
700 EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
701
702 EXPECT_EQ( 0, ZigZagDecode64(0u));
703 EXPECT_EQ(-1, ZigZagDecode64(1u));
704 EXPECT_EQ( 1, ZigZagDecode64(2u));
705 EXPECT_EQ(-2, ZigZagDecode64(3u));
706 EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
707 EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
708 EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
709 EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
710 EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
711 EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
712
713 // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
714 // were chosen semi-randomly via keyboard bashing.
715 EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0)));
716 EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1)));
717 EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1)));
718 EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
719 EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
720
721 EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0)));
722 EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1)));
723 EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1)));
724 EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
725 EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
726
727 EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64(
728 LL(856912304801416))));
729 EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64(
730 LL(-75123905439571256))));
731}
732
kenton@google.comfccb1462009-12-18 02:11:36 +0000733TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
734 // At one point checks would trigger when parsing repeated fixed scalar
735 // fields.
736 protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2;
737 for (int i = 0; i < 100; ++i) {
738 msg1.add_repeated_fixed32(i);
739 msg1.add_repeated_int32(i);
740 msg1.add_repeated_fixed64(i);
741 msg1.add_repeated_int64(i);
742 msg1.add_repeated_float(i);
743 msg1.add_repeated_uint64(i);
744 }
745
746 // Make sure that we have a variety of tag sizes.
747 const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
748 const google::protobuf::FieldDescriptor* field;
749 field = desc->FindFieldByName("repeated_fixed32");
750 ASSERT_TRUE(field != NULL);
751 ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
752 field = desc->FindFieldByName("repeated_int32");
753 ASSERT_TRUE(field != NULL);
754 ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
755 field = desc->FindFieldByName("repeated_fixed64");
756 ASSERT_TRUE(field != NULL);
757 ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
758 field = desc->FindFieldByName("repeated_int64");
759 ASSERT_TRUE(field != NULL);
760 ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
761 field = desc->FindFieldByName("repeated_float");
762 ASSERT_TRUE(field != NULL);
763 ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
764 field = desc->FindFieldByName("repeated_uint64");
765 ASSERT_TRUE(field != NULL);
766 ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
767
768 EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
769 EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
770}
771
jieluo@google.com4de8f552014-07-18 00:47:59 +0000772TEST(WireFormatTest, CompatibleTypes) {
Ezequiel Lara Gomezfb28d732015-04-27 09:35:27 +0100773 const int64 data = 0x100000000LL;
jieluo@google.com4de8f552014-07-18 00:47:59 +0000774 unittest::Int64Message msg1;
775 msg1.set_data(data);
776 string serialized;
777 msg1.SerializeToString(&serialized);
778
779 // Test int64 is compatible with bool
780 unittest::BoolMessage msg2;
781 ASSERT_TRUE(msg2.ParseFromString(serialized));
782 ASSERT_EQ(static_cast<bool>(data), msg2.data());
783
784 // Test int64 is compatible with uint64
785 unittest::Uint64Message msg3;
786 ASSERT_TRUE(msg3.ParseFromString(serialized));
787 ASSERT_EQ(static_cast<uint64>(data), msg3.data());
788
789 // Test int64 is compatible with int32
790 unittest::Int32Message msg4;
791 ASSERT_TRUE(msg4.ParseFromString(serialized));
792 ASSERT_EQ(static_cast<int32>(data), msg4.data());
793
794 // Test int64 is compatible with uint32
795 unittest::Uint32Message msg5;
796 ASSERT_TRUE(msg5.ParseFromString(serialized));
797 ASSERT_EQ(static_cast<uint32>(data), msg5.data());
798}
799
Bo Yanga269a6d2015-06-15 16:54:02 -0700800class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test {
Bo Yang5db21732015-05-21 14:28:59 -0700801 protected:
Bo Yanga269a6d2015-06-15 16:54:02 -0700802 Proto3PrimitiveRepeatedWireFormatTest()
803 : packedTestAllTypes_(
804 "\xFA\x01\x01\x01"
805 "\x82\x02\x01\x01"
806 "\x8A\x02\x01\x01"
807 "\x92\x02\x01\x01"
808 "\x9A\x02\x01\x02"
809 "\xA2\x02\x01\x02"
810 "\xAA\x02\x04\x01\x00\x00\x00"
811 "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
812 "\xBA\x02\x04\x01\x00\x00\x00"
813 "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
814 "\xCA\x02\x04\x00\x00\x80\x3f"
815 "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
816 "\xDA\x02\x01\x01"
817 "\x9A\x03\x01\x01",
818 86),
819 packedTestUnpackedTypes_(
820 "\x0A\x01\x01"
821 "\x12\x01\x01"
822 "\x1A\x01\x01"
823 "\x22\x01\x01"
824 "\x2A\x01\x02"
825 "\x32\x01\x02"
826 "\x3A\x04\x01\x00\x00\x00"
827 "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00"
828 "\x4A\x04\x01\x00\x00\x00"
829 "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00"
830 "\x5A\x04\x00\x00\x80\x3f"
831 "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
832 "\x6A\x01\x01"
833 "\x72\x01\x01",
834 72),
835 unpackedTestAllTypes_(
836 "\xF8\x01\x01"
837 "\x80\x02\x01"
838 "\x88\x02\x01"
839 "\x90\x02\x01"
840 "\x98\x02\x02"
841 "\xA0\x02\x02"
842 "\xAD\x02\x01\x00\x00\x00"
843 "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
844 "\xBD\x02\x01\x00\x00\x00"
845 "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
846 "\xCD\x02\x00\x00\x80\x3f"
847 "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f"
848 "\xD8\x02\x01"
849 "\x98\x03\x01",
850 72),
851 unpackedTestUnpackedTypes_(
852 "\x08\x01"
853 "\x10\x01"
854 "\x18\x01"
855 "\x20\x01"
856 "\x28\x02"
857 "\x30\x02"
858 "\x3D\x01\x00\x00\x00"
859 "\x41\x01\x00\x00\x00\x00\x00\x00\x00"
860 "\x4D\x01\x00\x00\x00"
861 "\x51\x01\x00\x00\x00\x00\x00\x00\x00"
862 "\x5D\x00\x00\x80\x3f"
863 "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
864 "\x68\x01"
865 "\x70\x01",
866 58) {}
Bo Yang5db21732015-05-21 14:28:59 -0700867 template <class Proto>
868 void SetProto3PrimitiveRepeatedFields(Proto* message) {
869 message->add_repeated_int32(1);
870 message->add_repeated_int64(1);
871 message->add_repeated_uint32(1);
872 message->add_repeated_uint64(1);
873 message->add_repeated_sint32(1);
874 message->add_repeated_sint64(1);
875 message->add_repeated_fixed32(1);
876 message->add_repeated_fixed64(1);
877 message->add_repeated_sfixed32(1);
878 message->add_repeated_sfixed64(1);
879 message->add_repeated_float(1.0);
880 message->add_repeated_double(1.0);
881 message->add_repeated_bool(true);
882 message->add_repeated_nested_enum(
883 proto3_arena_unittest::TestAllTypes_NestedEnum_FOO);
884 }
885
886 template <class Proto>
887 void ExpectProto3PrimitiveRepeatedFieldsSet(const Proto& message) {
888 EXPECT_EQ(1, message.repeated_int32(0));
889 EXPECT_EQ(1, message.repeated_int64(0));
890 EXPECT_EQ(1, message.repeated_uint32(0));
891 EXPECT_EQ(1, message.repeated_uint64(0));
892 EXPECT_EQ(1, message.repeated_sint32(0));
893 EXPECT_EQ(1, message.repeated_sint64(0));
894 EXPECT_EQ(1, message.repeated_fixed32(0));
895 EXPECT_EQ(1, message.repeated_fixed64(0));
896 EXPECT_EQ(1, message.repeated_sfixed32(0));
897 EXPECT_EQ(1, message.repeated_sfixed64(0));
898 EXPECT_EQ(1.0, message.repeated_float(0));
899 EXPECT_EQ(1.0, message.repeated_double(0));
900 EXPECT_EQ(true, message.repeated_bool(0));
901 EXPECT_EQ(proto3_arena_unittest::TestAllTypes_NestedEnum_FOO,
902 message.repeated_nested_enum(0));
903 }
904
905 template <class Proto>
Bo Yanga269a6d2015-06-15 16:54:02 -0700906 void TestSerialization(Proto* message, const string& expected) {
Bo Yang5db21732015-05-21 14:28:59 -0700907 SetProto3PrimitiveRepeatedFields(message);
908
909 int size = message->ByteSize();
910
911 // Serialize using the generated code.
912 string generated_data;
913 {
914 io::StringOutputStream raw_output(&generated_data);
915 io::CodedOutputStream output(&raw_output);
916 message->SerializeWithCachedSizes(&output);
917 ASSERT_FALSE(output.HadError());
918 }
Bo Yang5db21732015-05-21 14:28:59 -0700919 EXPECT_TRUE(expected == generated_data);
920
Bo Yang5db21732015-05-21 14:28:59 -0700921 // Serialize using the dynamic code.
922 string dynamic_data;
923 {
924 io::StringOutputStream raw_output(&dynamic_data);
925 io::CodedOutputStream output(&raw_output);
926 WireFormat::SerializeWithCachedSizes(*message, size, &output);
927 ASSERT_FALSE(output.HadError());
928 }
Bo Yang5db21732015-05-21 14:28:59 -0700929 EXPECT_TRUE(expected == dynamic_data);
Bo Yanga269a6d2015-06-15 16:54:02 -0700930 }
931
932 template <class Proto>
933 void TestParsing(Proto* message, const string& compatible_data) {
934 message->Clear();
935 message->ParseFromString(compatible_data);
936 ExpectProto3PrimitiveRepeatedFieldsSet(*message);
Bo Yang5db21732015-05-21 14:28:59 -0700937
938 message->Clear();
939 io::CodedInputStream input(
Bo Yanga269a6d2015-06-15 16:54:02 -0700940 reinterpret_cast<const uint8*>(compatible_data.data()),
941 compatible_data.size());
Bo Yang5db21732015-05-21 14:28:59 -0700942 WireFormat::ParseAndMergePartial(&input, message);
943 ExpectProto3PrimitiveRepeatedFieldsSet(*message);
944 }
Bo Yang5db21732015-05-21 14:28:59 -0700945
Bo Yanga269a6d2015-06-15 16:54:02 -0700946 const string packedTestAllTypes_;
947 const string packedTestUnpackedTypes_;
948 const string unpackedTestAllTypes_;
949 const string unpackedTestUnpackedTypes_;
950};
951
952TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
Bo Yang5db21732015-05-21 14:28:59 -0700953 proto3_arena_unittest::TestAllTypes packed_message;
954 proto3_arena_unittest::TestUnpackedTypes unpacked_message;
Bo Yanga269a6d2015-06-15 16:54:02 -0700955 TestSerialization(&packed_message, packedTestAllTypes_);
956 TestParsing(&packed_message, packedTestAllTypes_);
957 TestParsing(&packed_message, unpackedTestAllTypes_);
958 TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_);
959 TestParsing(&unpacked_message, packedTestUnpackedTypes_);
960 TestParsing(&unpacked_message, unpackedTestUnpackedTypes_);
Bo Yang5db21732015-05-21 14:28:59 -0700961}
962
temporal40ee5512008-07-10 02:12:20 +0000963class WireFormatInvalidInputTest : public testing::Test {
964 protected:
965 // Make a serialized TestAllTypes in which the field optional_nested_message
966 // contains exactly the given bytes, which may be invalid.
967 string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
968 const FieldDescriptor* field =
969 unittest::TestAllTypes::descriptor()->FindFieldByName(
970 "optional_nested_message");
971 GOOGLE_CHECK(field != NULL);
972
973 string result;
974
975 {
976 io::StringOutputStream raw_output(&result);
977 io::CodedOutputStream output(&raw_output);
978
kenton@google.com80b1d622009-07-29 01:13:20 +0000979 WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output);
temporal40ee5512008-07-10 02:12:20 +0000980 }
981
982 return result;
983 }
984
985 // Make a serialized TestAllTypes in which the field optionalgroup
986 // contains exactly the given bytes -- which may be invalid -- and
987 // possibly no end tag.
988 string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) {
989 const FieldDescriptor* field =
990 unittest::TestAllTypes::descriptor()->FindFieldByName(
991 "optionalgroup");
992 GOOGLE_CHECK(field != NULL);
993
994 string result;
995
996 {
997 io::StringOutputStream raw_output(&result);
998 io::CodedOutputStream output(&raw_output);
999
kenton@google.comd37d46d2009-04-25 02:53:47 +00001000 output.WriteVarint32(WireFormat::MakeTag(field));
1001 output.WriteString(string(bytes, size));
temporal40ee5512008-07-10 02:12:20 +00001002 if (include_end_tag) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001003 output.WriteVarint32(WireFormatLite::MakeTag(
1004 field->number(), WireFormatLite::WIRETYPE_END_GROUP));
temporal40ee5512008-07-10 02:12:20 +00001005 }
1006 }
1007
1008 return result;
1009 }
1010};
1011
1012TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
1013 unittest::TestAllTypes message;
1014
1015 // Control case.
1016 EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
1017
1018 // The byte is a valid varint, but not a valid tag (zero).
1019 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
1020
1021 // The byte is a malformed varint.
1022 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
1023
1024 // The byte is an endgroup tag, but we aren't parsing a group.
1025 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
1026
1027 // The byte is a valid varint but not a valid tag (bad wire type).
1028 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
1029}
1030
1031TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
1032 unittest::TestAllTypes message;
1033
1034 // Control case.
1035 EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
1036
1037 // Missing end tag. Groups cannot end at EOF.
1038 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
1039
1040 // The byte is a valid varint, but not a valid tag (zero).
1041 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
1042
1043 // The byte is a malformed varint.
1044 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
1045
1046 // The byte is an endgroup tag, but not the right one for this group.
1047 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
1048
1049 // The byte is a valid varint but not a valid tag (bad wire type).
1050 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
1051}
1052
1053TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
temporal779f61c2008-08-13 03:15:00 +00001054 // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
temporal40ee5512008-07-10 02:12:20 +00001055 // be a known tag number.
temporal779f61c2008-08-13 03:15:00 +00001056 unittest::TestEmptyMessage message;
temporal40ee5512008-07-10 02:12:20 +00001057
1058 // Control case.
1059 EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
1060
1061 // Missing end tag. Groups cannot end at EOF.
1062 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
1063
1064 // The byte is a valid varint, but not a valid tag (zero).
1065 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
1066
1067 // The byte is a malformed varint.
1068 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
1069
1070 // The byte is an endgroup tag, but not the right one for this group.
1071 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
1072
1073 // The byte is a valid varint but not a valid tag (bad wire type).
1074 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
1075}
1076
temporal779f61c2008-08-13 03:15:00 +00001077TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
1078 // Test a bug fix: SkipMessage should fail if the message contains a string
1079 // whose length would extend beyond the message end.
1080
1081 unittest::TestAllTypes message;
1082 message.set_optional_string("foo foo foo foo");
1083 string data;
1084 message.SerializeToString(&data);
1085
1086 // Chop some bytes off the end.
1087 data.resize(data.size() - 4);
1088
1089 // Try to skip it. Note that the bug was only present when parsing to an
1090 // UnknownFieldSet.
1091 io::ArrayInputStream raw_input(data.data(), data.size());
1092 io::CodedInputStream coded_input(&raw_input);
1093 UnknownFieldSet unknown_fields;
1094 EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
1095}
1096
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001097// Test differences between string and bytes.
1098// Value of a string type must be valid UTF-8 string. When UTF-8
1099// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
1100// WriteInvalidUTF8String: see error message.
1101// ReadInvalidUTF8String: see error message.
1102// WriteValidUTF8String: fine.
1103// ReadValidUTF8String: fine.
1104// WriteAnyBytes: fine.
1105// ReadAnyBytes: fine.
1106const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
kenton@google.com503a4dd2009-04-28 02:16:53 +00001107// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
1108// interpret \u differently from GCC.
1109const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001110
1111template<typename T>
1112bool WriteMessage(const char *value, T *message, string *wire_buffer) {
1113 message->set_data(value);
1114 wire_buffer->clear();
1115 message->AppendToString(wire_buffer);
1116 return (wire_buffer->size() > 0);
1117}
1118
1119template<typename T>
1120bool ReadMessage(const string &wire_buffer, T *message) {
1121 return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
1122}
1123
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001124bool StartsWith(const string& s, const string& prefix) {
1125 return s.substr(0, prefix.length()) == prefix;
1126}
1127
jieluo@google.com4de8f552014-07-18 00:47:59 +00001128class Utf8ValidationTest : public ::testing::Test {
1129 protected:
1130 Utf8ValidationTest() {}
1131 virtual ~Utf8ValidationTest() {}
1132 virtual void SetUp() {
1133 }
1134
1135};
1136
1137TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001138 string wire_buffer;
1139 protobuf_unittest::OneString input;
1140 vector<string> errors;
1141 {
1142 ScopedMemoryLog log;
1143 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1144 errors = log.GetMessages(ERROR);
1145 }
1146#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1147 ASSERT_EQ(1, errors.size());
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001148 EXPECT_TRUE(StartsWith(errors[0],
Feng Xiao6ef984a2014-11-10 17:34:54 -08001149 "String field 'protobuf_unittest.OneString.data' "
1150 "contains invalid UTF-8 data when "
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001151 "serializing a protocol buffer. Use the "
1152 "'bytes' type if you intend to send raw bytes."));
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001153#else
1154 ASSERT_EQ(0, errors.size());
1155#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1156}
1157
jieluo@google.com4de8f552014-07-18 00:47:59 +00001158
1159TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001160 string wire_buffer;
1161 protobuf_unittest::OneString input;
1162 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1163 protobuf_unittest::OneString output;
1164 vector<string> errors;
1165 {
1166 ScopedMemoryLog log;
1167 ReadMessage(wire_buffer, &output);
1168 errors = log.GetMessages(ERROR);
1169 }
1170#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1171 ASSERT_EQ(1, errors.size());
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001172 EXPECT_TRUE(StartsWith(errors[0],
Feng Xiao6ef984a2014-11-10 17:34:54 -08001173 "String field 'protobuf_unittest.OneString.data' "
1174 "contains invalid UTF-8 data when "
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001175 "parsing a protocol buffer. Use the "
1176 "'bytes' type if you intend to send raw bytes."));
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001177
1178#else
1179 ASSERT_EQ(0, errors.size());
1180#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1181}
1182
jieluo@google.com4de8f552014-07-18 00:47:59 +00001183
1184TEST_F(Utf8ValidationTest, WriteValidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001185 string wire_buffer;
1186 protobuf_unittest::OneString input;
1187 vector<string> errors;
1188 {
1189 ScopedMemoryLog log;
1190 WriteMessage(kValidUTF8String, &input, &wire_buffer);
1191 errors = log.GetMessages(ERROR);
1192 }
1193 ASSERT_EQ(0, errors.size());
1194}
1195
jieluo@google.com4de8f552014-07-18 00:47:59 +00001196TEST_F(Utf8ValidationTest, ReadValidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001197 string wire_buffer;
1198 protobuf_unittest::OneString input;
1199 WriteMessage(kValidUTF8String, &input, &wire_buffer);
1200 protobuf_unittest::OneString output;
1201 vector<string> errors;
1202 {
1203 ScopedMemoryLog log;
1204 ReadMessage(wire_buffer, &output);
1205 errors = log.GetMessages(ERROR);
1206 }
1207 ASSERT_EQ(0, errors.size());
1208 EXPECT_EQ(input.data(), output.data());
1209}
1210
1211// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
jieluo@google.com4de8f552014-07-18 00:47:59 +00001212TEST_F(Utf8ValidationTest, WriteArbitraryBytes) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001213 string wire_buffer;
1214 protobuf_unittest::OneBytes input;
1215 vector<string> errors;
1216 {
1217 ScopedMemoryLog log;
1218 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1219 errors = log.GetMessages(ERROR);
1220 }
1221 ASSERT_EQ(0, errors.size());
1222}
1223
jieluo@google.com4de8f552014-07-18 00:47:59 +00001224TEST_F(Utf8ValidationTest, ReadArbitraryBytes) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001225 string wire_buffer;
1226 protobuf_unittest::OneBytes input;
1227 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1228 protobuf_unittest::OneBytes output;
1229 vector<string> errors;
1230 {
1231 ScopedMemoryLog log;
1232 ReadMessage(wire_buffer, &output);
1233 errors = log.GetMessages(ERROR);
1234 }
1235 ASSERT_EQ(0, errors.size());
1236 EXPECT_EQ(input.data(), output.data());
1237}
1238
jieluo@google.com4de8f552014-07-18 00:47:59 +00001239TEST_F(Utf8ValidationTest, ParseRepeatedString) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001240 protobuf_unittest::MoreBytes input;
1241 input.add_data(kValidUTF8String);
1242 input.add_data(kInvalidUTF8String);
1243 input.add_data(kInvalidUTF8String);
1244 string wire_buffer = input.SerializeAsString();
1245
1246 protobuf_unittest::MoreString output;
1247 vector<string> errors;
1248 {
1249 ScopedMemoryLog log;
1250 ReadMessage(wire_buffer, &output);
1251 errors = log.GetMessages(ERROR);
1252 }
1253#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1254 ASSERT_EQ(2, errors.size());
1255#else
1256 ASSERT_EQ(0, errors.size());
1257#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1258 EXPECT_EQ(wire_buffer, output.SerializeAsString());
1259}
1260
jieluo@google.com4de8f552014-07-18 00:47:59 +00001261// Test the old VerifyUTF8String() function, which may still be called by old
1262// generated code.
1263TEST_F(Utf8ValidationTest, OldVerifyUTF8String) {
1264 string data(kInvalidUTF8String);
1265
1266 vector<string> errors;
1267 {
1268 ScopedMemoryLog log;
1269 WireFormat::VerifyUTF8String(data.data(), data.size(),
1270 WireFormat::SERIALIZE);
1271 errors = log.GetMessages(ERROR);
1272 }
1273#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1274 ASSERT_EQ(1, errors.size());
1275 EXPECT_TRUE(StartsWith(errors[0],
1276 "String field contains invalid UTF-8 data when "
1277 "serializing a protocol buffer. Use the "
1278 "'bytes' type if you intend to send raw bytes."));
1279#else
1280 ASSERT_EQ(0, errors.size());
1281#endif
1282}
1283
1284
temporal40ee5512008-07-10 02:12:20 +00001285} // namespace
1286} // namespace internal
1287} // namespace protobuf
1288} // namespace google