blob: 4e4add66f3308f802dc5c9097ca7c4b54beec494 [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>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070048#include <google/protobuf/stubs/logging.h>
temporal40ee5512008-07-10 02:12:20 +000049#include <google/protobuf/testing/googletest.h>
50#include <gtest/gtest.h>
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000051#include <google/protobuf/stubs/stl_util.h>
temporal40ee5512008-07-10 02:12:20 +000052
53namespace google {
54namespace protobuf {
55namespace internal {
56namespace {
57
kenton@google.com80b1d622009-07-29 01:13:20 +000058TEST(WireFormatTest, EnumsInSync) {
59 // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
60 // FieldDescriptor::Type and FieldDescriptor::CppType.
61
62 EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
63 implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
64 EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
65 implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
66
67 for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
68 EXPECT_EQ(
69 implicit_cast<int>(FieldDescriptor::TypeToCppType(
70 static_cast<FieldDescriptor::Type>(i))),
71 implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
72 static_cast<WireFormatLite::FieldType>(i))));
73 }
74}
75
temporal40ee5512008-07-10 02:12:20 +000076TEST(WireFormatTest, MaxFieldNumber) {
77 // Make sure the max field number constant is accurate.
kenton@google.com80b1d622009-07-29 01:13:20 +000078 EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1,
temporal40ee5512008-07-10 02:12:20 +000079 FieldDescriptor::kMaxNumber);
80}
81
82TEST(WireFormatTest, Parse) {
83 unittest::TestAllTypes source, dest;
84 string data;
85
86 // Serialize using the generated code.
87 TestUtil::SetAllFields(&source);
88 source.SerializeToString(&data);
89
90 // Parse using WireFormat.
91 io::ArrayInputStream raw_input(data.data(), data.size());
92 io::CodedInputStream input(&raw_input);
temporal779f61c2008-08-13 03:15:00 +000093 WireFormat::ParseAndMergePartial(&input, &dest);
temporal40ee5512008-07-10 02:12:20 +000094
95 // Check.
96 TestUtil::ExpectAllFieldsSet(dest);
97}
98
99TEST(WireFormatTest, ParseExtensions) {
100 unittest::TestAllExtensions source, dest;
101 string data;
102
103 // Serialize using the generated code.
104 TestUtil::SetAllExtensions(&source);
105 source.SerializeToString(&data);
106
107 // Parse using WireFormat.
108 io::ArrayInputStream raw_input(data.data(), data.size());
109 io::CodedInputStream input(&raw_input);
temporal779f61c2008-08-13 03:15:00 +0000110 WireFormat::ParseAndMergePartial(&input, &dest);
temporal40ee5512008-07-10 02:12:20 +0000111
112 // Check.
113 TestUtil::ExpectAllExtensionsSet(dest);
114}
115
kenton@google.com2d6daa72009-01-22 01:27:00 +0000116TEST(WireFormatTest, ParsePacked) {
117 unittest::TestPackedTypes source, dest;
118 string data;
119
120 // Serialize using the generated code.
121 TestUtil::SetPackedFields(&source);
122 source.SerializeToString(&data);
123
124 // Parse using WireFormat.
125 io::ArrayInputStream raw_input(data.data(), data.size());
126 io::CodedInputStream input(&raw_input);
127 WireFormat::ParseAndMergePartial(&input, &dest);
128
129 // Check.
130 TestUtil::ExpectPackedFieldsSet(dest);
131}
132
kenton@google.comfccb1462009-12-18 02:11:36 +0000133TEST(WireFormatTest, ParsePackedFromUnpacked) {
134 // Serialize using the generated code.
135 unittest::TestUnpackedTypes source;
136 TestUtil::SetUnpackedFields(&source);
137 string data = source.SerializeAsString();
138
139 // Parse using WireFormat.
140 unittest::TestPackedTypes dest;
141 io::ArrayInputStream raw_input(data.data(), data.size());
142 io::CodedInputStream input(&raw_input);
143 WireFormat::ParseAndMergePartial(&input, &dest);
144
145 // Check.
146 TestUtil::ExpectPackedFieldsSet(dest);
147}
148
149TEST(WireFormatTest, ParseUnpackedFromPacked) {
150 // Serialize using the generated code.
151 unittest::TestPackedTypes source;
152 TestUtil::SetPackedFields(&source);
153 string data = source.SerializeAsString();
154
155 // Parse using WireFormat.
156 unittest::TestUnpackedTypes dest;
157 io::ArrayInputStream raw_input(data.data(), data.size());
158 io::CodedInputStream input(&raw_input);
159 WireFormat::ParseAndMergePartial(&input, &dest);
160
161 // Check.
162 TestUtil::ExpectUnpackedFieldsSet(dest);
163}
164
kenton@google.com2d6daa72009-01-22 01:27:00 +0000165TEST(WireFormatTest, ParsePackedExtensions) {
166 unittest::TestPackedExtensions source, dest;
167 string data;
168
169 // Serialize using the generated code.
170 TestUtil::SetPackedExtensions(&source);
171 source.SerializeToString(&data);
172
173 // Parse using WireFormat.
174 io::ArrayInputStream raw_input(data.data(), data.size());
175 io::CodedInputStream input(&raw_input);
176 WireFormat::ParseAndMergePartial(&input, &dest);
177
178 // Check.
179 TestUtil::ExpectPackedExtensionsSet(dest);
180}
181
jieluo@google.com4de8f552014-07-18 00:47:59 +0000182TEST(WireFormatTest, ParseOneof) {
183 unittest::TestOneof2 source, dest;
184 string data;
185
186 // Serialize using the generated code.
187 TestUtil::SetOneof1(&source);
188 source.SerializeToString(&data);
189
190 // Parse using WireFormat.
191 io::ArrayInputStream raw_input(data.data(), data.size());
192 io::CodedInputStream input(&raw_input);
193 WireFormat::ParseAndMergePartial(&input, &dest);
194
195 // Check.
196 TestUtil::ExpectOneofSet1(dest);
197}
198
199TEST(WireFormatTest, OneofOnlySetLast) {
200 unittest::TestOneofBackwardsCompatible source;
201 unittest::TestOneof oneof_dest;
202 string data;
203
204 // Set two fields
205 source.set_foo_int(100);
206 source.set_foo_string("101");
207
208 // Serialize and parse to oneof message.
209 source.SerializeToString(&data);
210 io::ArrayInputStream raw_input(data.data(), data.size());
211 io::CodedInputStream input(&raw_input);
212 WireFormat::ParseAndMergePartial(&input, &oneof_dest);
213
214 // Only the last field is set.
215 EXPECT_FALSE(oneof_dest.has_foo_int());
216 EXPECT_TRUE(oneof_dest.has_foo_string());
217}
218
temporal40ee5512008-07-10 02:12:20 +0000219TEST(WireFormatTest, ByteSize) {
220 unittest::TestAllTypes message;
221 TestUtil::SetAllFields(&message);
222
temporal779f61c2008-08-13 03:15:00 +0000223 EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000224 message.Clear();
225 EXPECT_EQ(0, message.ByteSize());
temporal779f61c2008-08-13 03:15:00 +0000226 EXPECT_EQ(0, WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000227}
228
229TEST(WireFormatTest, ByteSizeExtensions) {
230 unittest::TestAllExtensions message;
231 TestUtil::SetAllExtensions(&message);
232
233 EXPECT_EQ(message.ByteSize(),
temporal779f61c2008-08-13 03:15:00 +0000234 WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000235 message.Clear();
236 EXPECT_EQ(0, message.ByteSize());
temporal779f61c2008-08-13 03:15:00 +0000237 EXPECT_EQ(0, WireFormat::ByteSize(message));
temporal40ee5512008-07-10 02:12:20 +0000238}
239
kenton@google.com2d6daa72009-01-22 01:27:00 +0000240TEST(WireFormatTest, ByteSizePacked) {
241 unittest::TestPackedTypes message;
242 TestUtil::SetPackedFields(&message);
243
244 EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
245 message.Clear();
246 EXPECT_EQ(0, message.ByteSize());
247 EXPECT_EQ(0, WireFormat::ByteSize(message));
248}
249
250TEST(WireFormatTest, ByteSizePackedExtensions) {
251 unittest::TestPackedExtensions message;
252 TestUtil::SetPackedExtensions(&message);
253
254 EXPECT_EQ(message.ByteSize(),
255 WireFormat::ByteSize(message));
256 message.Clear();
257 EXPECT_EQ(0, message.ByteSize());
258 EXPECT_EQ(0, WireFormat::ByteSize(message));
259}
260
jieluo@google.com4de8f552014-07-18 00:47:59 +0000261TEST(WireFormatTest, ByteSizeOneof) {
262 unittest::TestOneof2 message;
263 TestUtil::SetOneof1(&message);
264
265 EXPECT_EQ(message.ByteSize(),
266 WireFormat::ByteSize(message));
267 message.Clear();
268
269 EXPECT_EQ(0, message.ByteSize());
270 EXPECT_EQ(0, WireFormat::ByteSize(message));
271}
272
temporal40ee5512008-07-10 02:12:20 +0000273TEST(WireFormatTest, Serialize) {
274 unittest::TestAllTypes message;
275 string generated_data;
276 string dynamic_data;
277
278 TestUtil::SetAllFields(&message);
279 int size = message.ByteSize();
280
281 // Serialize using the generated code.
282 {
283 io::StringOutputStream raw_output(&generated_data);
284 io::CodedOutputStream output(&raw_output);
285 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000286 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000287 }
288
289 // Serialize using WireFormat.
290 {
291 io::StringOutputStream raw_output(&dynamic_data);
292 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000293 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000294 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000295 }
296
297 // Should be the same.
298 // Don't use EXPECT_EQ here because we're comparing raw binary data and
299 // we really don't want it dumped to stdout on failure.
300 EXPECT_TRUE(dynamic_data == generated_data);
301}
302
303TEST(WireFormatTest, SerializeExtensions) {
304 unittest::TestAllExtensions message;
305 string generated_data;
306 string dynamic_data;
307
308 TestUtil::SetAllExtensions(&message);
309 int size = message.ByteSize();
310
311 // Serialize using the generated code.
312 {
313 io::StringOutputStream raw_output(&generated_data);
314 io::CodedOutputStream output(&raw_output);
315 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000316 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000317 }
318
319 // Serialize using WireFormat.
320 {
321 io::StringOutputStream raw_output(&dynamic_data);
322 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000323 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000324 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000325 }
326
327 // Should be the same.
328 // Don't use EXPECT_EQ here because we're comparing raw binary data and
329 // we really don't want it dumped to stdout on failure.
330 EXPECT_TRUE(dynamic_data == generated_data);
331}
332
333TEST(WireFormatTest, SerializeFieldsAndExtensions) {
334 unittest::TestFieldOrderings message;
335 string generated_data;
336 string dynamic_data;
337
338 TestUtil::SetAllFieldsAndExtensions(&message);
339 int size = message.ByteSize();
340
341 // Serialize using the generated code.
342 {
343 io::StringOutputStream raw_output(&generated_data);
344 io::CodedOutputStream output(&raw_output);
345 message.SerializeWithCachedSizes(&output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000346 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000347 }
348
349 // Serialize using WireFormat.
350 {
351 io::StringOutputStream raw_output(&dynamic_data);
352 io::CodedOutputStream output(&raw_output);
temporal779f61c2008-08-13 03:15:00 +0000353 WireFormat::SerializeWithCachedSizes(message, size, &output);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000354 ASSERT_FALSE(output.HadError());
temporal40ee5512008-07-10 02:12:20 +0000355 }
356
357 // Should be the same.
358 // Don't use EXPECT_EQ here because we're comparing raw binary data and
359 // we really don't want it dumped to stdout on failure.
360 EXPECT_TRUE(dynamic_data == generated_data);
361
362 // Should output in canonical order.
363 TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data);
364 TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
365}
366
jieluo@google.com4de8f552014-07-18 00:47:59 +0000367TEST(WireFormatTest, SerializeOneof) {
368 unittest::TestOneof2 message;
369 string generated_data;
370 string dynamic_data;
371
372 TestUtil::SetOneof1(&message);
373 int size = message.ByteSize();
374
375 // Serialize using the generated code.
376 {
377 io::StringOutputStream raw_output(&generated_data);
378 io::CodedOutputStream output(&raw_output);
379 message.SerializeWithCachedSizes(&output);
380 ASSERT_FALSE(output.HadError());
381 }
382
383 // Serialize using WireFormat.
384 {
385 io::StringOutputStream raw_output(&dynamic_data);
386 io::CodedOutputStream output(&raw_output);
387 WireFormat::SerializeWithCachedSizes(message, size, &output);
388 ASSERT_FALSE(output.HadError());
389 }
390
391 // Should be the same.
392 // Don't use EXPECT_EQ here because we're comparing raw binary data and
393 // we really don't want it dumped to stdout on failure.
394 EXPECT_TRUE(dynamic_data == generated_data);
395}
396
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000397TEST(WireFormatTest, ParseMultipleExtensionRanges) {
398 // Make sure we can parse a message that contains multiple extensions ranges.
399 unittest::TestFieldOrderings source;
400 string data;
401
402 TestUtil::SetAllFieldsAndExtensions(&source);
403 source.SerializeToString(&data);
404
405 {
406 unittest::TestFieldOrderings dest;
407 EXPECT_TRUE(dest.ParseFromString(data));
408 EXPECT_EQ(source.DebugString(), dest.DebugString());
409 }
410
411 // Also test using reflection-based parsing.
412 {
413 unittest::TestFieldOrderings dest;
414 io::ArrayInputStream raw_input(data.data(), data.size());
415 io::CodedInputStream coded_input(&raw_input);
416 EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
417 EXPECT_EQ(source.DebugString(), dest.DebugString());
418 }
419}
420
temporal40ee5512008-07-10 02:12:20 +0000421const int kUnknownTypeId = 1550055;
422
423TEST(WireFormatTest, SerializeMessageSet) {
424 // Set up a TestMessageSet with two known messages and an unknown one.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700425 proto2_wireformat_unittest::TestMessageSet message_set;
temporal40ee5512008-07-10 02:12:20 +0000426 message_set.MutableExtension(
427 unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
428 message_set.MutableExtension(
429 unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
kenton@google.comd37d46d2009-04-25 02:53:47 +0000430 message_set.mutable_unknown_fields()->AddLengthDelimited(
431 kUnknownTypeId, "bar");
temporal40ee5512008-07-10 02:12:20 +0000432
433 string data;
434 ASSERT_TRUE(message_set.SerializeToString(&data));
435
436 // Parse back using RawMessageSet and check the contents.
437 unittest::RawMessageSet raw;
438 ASSERT_TRUE(raw.ParseFromString(data));
439
440 EXPECT_EQ(0, raw.unknown_fields().field_count());
441
442 ASSERT_EQ(3, raw.item_size());
443 EXPECT_EQ(
444 unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(),
445 raw.item(0).type_id());
446 EXPECT_EQ(
447 unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(),
448 raw.item(1).type_id());
449 EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
450
451 unittest::TestMessageSetExtension1 message1;
452 EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
453 EXPECT_EQ(123, message1.i());
454
455 unittest::TestMessageSetExtension2 message2;
456 EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
457 EXPECT_EQ("foo", message2.str());
458
459 EXPECT_EQ("bar", raw.item(2).message());
460}
461
kenton@google.com80b1d622009-07-29 01:13:20 +0000462TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
463 // Serialize a MessageSet to a stream and to a flat array using generated
464 // code, and also using WireFormat, and check that the results are equal.
kenton@google.comd37d46d2009-04-25 02:53:47 +0000465 // Set up a TestMessageSet with two known messages and an unknown one, as
466 // above.
467
Feng Xiaoeee38b02015-08-22 18:25:48 -0700468 proto2_wireformat_unittest::TestMessageSet message_set;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000469 message_set.MutableExtension(
470 unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
471 message_set.MutableExtension(
472 unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
473 message_set.mutable_unknown_fields()->AddLengthDelimited(
474 kUnknownTypeId, "bar");
475
476 int size = message_set.ByteSize();
kenton@google.com80b1d622009-07-29 01:13:20 +0000477 EXPECT_EQ(size, message_set.GetCachedSize());
478 ASSERT_EQ(size, WireFormat::ByteSize(message_set));
479
kenton@google.comd37d46d2009-04-25 02:53:47 +0000480 string flat_data;
481 string stream_data;
kenton@google.com80b1d622009-07-29 01:13:20 +0000482 string dynamic_data;
kenton@google.comd37d46d2009-04-25 02:53:47 +0000483 flat_data.resize(size);
484 stream_data.resize(size);
kenton@google.com80b1d622009-07-29 01:13:20 +0000485
kenton@google.comd37d46d2009-04-25 02:53:47 +0000486 // Serialize to flat array
487 {
488 uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
489 uint8* end = message_set.SerializeWithCachedSizesToArray(target);
490 EXPECT_EQ(size, end - target);
491 }
492
493 // Serialize to buffer
494 {
495 io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
496 io::CodedOutputStream output_stream(&array_stream);
497 message_set.SerializeWithCachedSizes(&output_stream);
498 ASSERT_FALSE(output_stream.HadError());
499 }
500
kenton@google.com80b1d622009-07-29 01:13:20 +0000501 // Serialize to buffer with WireFormat.
502 {
503 io::StringOutputStream string_stream(&dynamic_data);
504 io::CodedOutputStream output_stream(&string_stream);
505 WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
506 ASSERT_FALSE(output_stream.HadError());
507 }
508
kenton@google.comd37d46d2009-04-25 02:53:47 +0000509 EXPECT_TRUE(flat_data == stream_data);
kenton@google.com80b1d622009-07-29 01:13:20 +0000510 EXPECT_TRUE(flat_data == dynamic_data);
kenton@google.comd37d46d2009-04-25 02:53:47 +0000511}
512
temporal40ee5512008-07-10 02:12:20 +0000513TEST(WireFormatTest, ParseMessageSet) {
514 // Set up a RawMessageSet with two known messages and an unknown one.
515 unittest::RawMessageSet raw;
516
517 {
518 unittest::RawMessageSet::Item* item = raw.add_item();
519 item->set_type_id(
520 unittest::TestMessageSetExtension1::descriptor()->extension(0)->number());
521 unittest::TestMessageSetExtension1 message;
522 message.set_i(123);
523 message.SerializeToString(item->mutable_message());
524 }
525
526 {
527 unittest::RawMessageSet::Item* item = raw.add_item();
528 item->set_type_id(
529 unittest::TestMessageSetExtension2::descriptor()->extension(0)->number());
530 unittest::TestMessageSetExtension2 message;
531 message.set_str("foo");
532 message.SerializeToString(item->mutable_message());
533 }
534
535 {
536 unittest::RawMessageSet::Item* item = raw.add_item();
537 item->set_type_id(kUnknownTypeId);
538 item->set_message("bar");
539 }
540
541 string data;
542 ASSERT_TRUE(raw.SerializeToString(&data));
543
544 // Parse as a TestMessageSet and check the contents.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700545 proto2_wireformat_unittest::TestMessageSet message_set;
temporal40ee5512008-07-10 02:12:20 +0000546 ASSERT_TRUE(message_set.ParseFromString(data));
547
548 EXPECT_EQ(123, message_set.GetExtension(
549 unittest::TestMessageSetExtension1::message_set_extension).i());
550 EXPECT_EQ("foo", message_set.GetExtension(
551 unittest::TestMessageSetExtension2::message_set_extension).str());
552
553 ASSERT_EQ(1, message_set.unknown_fields().field_count());
kenton@google.comd37d46d2009-04-25 02:53:47 +0000554 ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED,
555 message_set.unknown_fields().field(0).type());
556 EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
kenton@google.com80b1d622009-07-29 01:13:20 +0000557
558 // Also parse using WireFormat.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700559 proto2_wireformat_unittest::TestMessageSet dynamic_message_set;
kenton@google.com80b1d622009-07-29 01:13:20 +0000560 io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
561 data.size());
562 ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
563 EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
temporal40ee5512008-07-10 02:12:20 +0000564}
565
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000566TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
567 string data;
568 {
569 unittest::TestMessageSetExtension1 message;
570 message.set_i(123);
571 // Build a MessageSet manually with its message content put before its
572 // type_id.
573 io::StringOutputStream output_stream(&data);
574 io::CodedOutputStream coded_output(&output_stream);
575 coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
576 // Write the message content first.
577 WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
578 WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
579 &coded_output);
580 coded_output.WriteVarint32(message.ByteSize());
581 message.SerializeWithCachedSizes(&coded_output);
582 // Write the type id.
xiaofeng@google.comfcb8a502012-09-24 06:48:20 +0000583 uint32 type_id = message.GetDescriptor()->extension(0)->number();
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000584 WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
585 type_id, &coded_output);
586 coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
587 }
588 {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700589 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000590 ASSERT_TRUE(message_set.ParseFromString(data));
591
592 EXPECT_EQ(123, message_set.GetExtension(
593 unittest::TestMessageSetExtension1::message_set_extension).i());
594 }
595 {
596 // Test parse the message via Reflection.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700597 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000598 io::CodedInputStream input(
599 reinterpret_cast<const uint8*>(data.data()), data.size());
600 EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
601 EXPECT_TRUE(input.ConsumedEntireMessage());
602
603 EXPECT_EQ(123, message_set.GetExtension(
604 unittest::TestMessageSetExtension1::message_set_extension).i());
605 }
606}
607
608TEST(WireFormatTest, ParseBrokenMessageSet) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700609 proto2_wireformat_unittest::TestMessageSet message_set;
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000610 string input("goodbye"); // Invalid wire format data.
611 EXPECT_FALSE(message_set.ParseFromString(input));
612}
613
temporal40ee5512008-07-10 02:12:20 +0000614TEST(WireFormatTest, RecursionLimit) {
615 unittest::TestRecursiveMessage message;
616 message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
617 string data;
618 message.SerializeToString(&data);
619
620 {
621 io::ArrayInputStream raw_input(data.data(), data.size());
622 io::CodedInputStream input(&raw_input);
623 input.SetRecursionLimit(4);
624 unittest::TestRecursiveMessage message2;
625 EXPECT_TRUE(message2.ParseFromCodedStream(&input));
626 }
627
628 {
629 io::ArrayInputStream raw_input(data.data(), data.size());
630 io::CodedInputStream input(&raw_input);
631 input.SetRecursionLimit(3);
632 unittest::TestRecursiveMessage message2;
633 EXPECT_FALSE(message2.ParseFromCodedStream(&input));
634 }
635}
636
637TEST(WireFormatTest, UnknownFieldRecursionLimit) {
638 unittest::TestEmptyMessage message;
639 message.mutable_unknown_fields()
kenton@google.comd37d46d2009-04-25 02:53:47 +0000640 ->AddGroup(1234)
641 ->AddGroup(1234)
642 ->AddGroup(1234)
643 ->AddGroup(1234)
644 ->AddVarint(1234, 123);
temporal40ee5512008-07-10 02:12:20 +0000645 string data;
646 message.SerializeToString(&data);
647
648 {
649 io::ArrayInputStream raw_input(data.data(), data.size());
650 io::CodedInputStream input(&raw_input);
651 input.SetRecursionLimit(4);
652 unittest::TestEmptyMessage message2;
653 EXPECT_TRUE(message2.ParseFromCodedStream(&input));
654 }
655
656 {
657 io::ArrayInputStream raw_input(data.data(), data.size());
658 io::CodedInputStream input(&raw_input);
659 input.SetRecursionLimit(3);
660 unittest::TestEmptyMessage message2;
661 EXPECT_FALSE(message2.ParseFromCodedStream(&input));
662 }
663}
664
665TEST(WireFormatTest, ZigZag) {
666// avoid line-wrapping
667#define LL(x) GOOGLE_LONGLONG(x)
668#define ULL(x) GOOGLE_ULONGLONG(x)
kenton@google.com80b1d622009-07-29 01:13:20 +0000669#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x)
670#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
671#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
672#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x)
temporal40ee5512008-07-10 02:12:20 +0000673
674 EXPECT_EQ(0u, ZigZagEncode32( 0));
675 EXPECT_EQ(1u, ZigZagEncode32(-1));
676 EXPECT_EQ(2u, ZigZagEncode32( 1));
677 EXPECT_EQ(3u, ZigZagEncode32(-2));
678 EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
679 EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
680 EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
681 EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
682
683 EXPECT_EQ( 0, ZigZagDecode32(0u));
684 EXPECT_EQ(-1, ZigZagDecode32(1u));
685 EXPECT_EQ( 1, ZigZagDecode32(2u));
686 EXPECT_EQ(-2, ZigZagDecode32(3u));
687 EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
688 EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
689 EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
690 EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
691
692 EXPECT_EQ(0u, ZigZagEncode64( 0));
693 EXPECT_EQ(1u, ZigZagEncode64(-1));
694 EXPECT_EQ(2u, ZigZagEncode64( 1));
695 EXPECT_EQ(3u, ZigZagEncode64(-2));
696 EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
697 EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
698 EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
699 EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
700 EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
701 EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
702
703 EXPECT_EQ( 0, ZigZagDecode64(0u));
704 EXPECT_EQ(-1, ZigZagDecode64(1u));
705 EXPECT_EQ( 1, ZigZagDecode64(2u));
706 EXPECT_EQ(-2, ZigZagDecode64(3u));
707 EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
708 EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
709 EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
710 EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
711 EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
712 EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
713
714 // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
715 // were chosen semi-randomly via keyboard bashing.
716 EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0)));
717 EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1)));
718 EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1)));
719 EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
720 EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
721
722 EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0)));
723 EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1)));
724 EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1)));
725 EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
726 EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
727
728 EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64(
729 LL(856912304801416))));
730 EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64(
731 LL(-75123905439571256))));
732}
733
kenton@google.comfccb1462009-12-18 02:11:36 +0000734TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
735 // At one point checks would trigger when parsing repeated fixed scalar
736 // fields.
737 protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2;
738 for (int i = 0; i < 100; ++i) {
739 msg1.add_repeated_fixed32(i);
740 msg1.add_repeated_int32(i);
741 msg1.add_repeated_fixed64(i);
742 msg1.add_repeated_int64(i);
743 msg1.add_repeated_float(i);
744 msg1.add_repeated_uint64(i);
745 }
746
747 // Make sure that we have a variety of tag sizes.
748 const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
749 const google::protobuf::FieldDescriptor* field;
750 field = desc->FindFieldByName("repeated_fixed32");
751 ASSERT_TRUE(field != NULL);
752 ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
753 field = desc->FindFieldByName("repeated_int32");
754 ASSERT_TRUE(field != NULL);
755 ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
756 field = desc->FindFieldByName("repeated_fixed64");
757 ASSERT_TRUE(field != NULL);
758 ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
759 field = desc->FindFieldByName("repeated_int64");
760 ASSERT_TRUE(field != NULL);
761 ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
762 field = desc->FindFieldByName("repeated_float");
763 ASSERT_TRUE(field != NULL);
764 ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
765 field = desc->FindFieldByName("repeated_uint64");
766 ASSERT_TRUE(field != NULL);
767 ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
768
769 EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
770 EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
771}
772
jieluo@google.com4de8f552014-07-18 00:47:59 +0000773TEST(WireFormatTest, CompatibleTypes) {
Ezequiel Lara Gomezfb28d732015-04-27 09:35:27 +0100774 const int64 data = 0x100000000LL;
jieluo@google.com4de8f552014-07-18 00:47:59 +0000775 unittest::Int64Message msg1;
776 msg1.set_data(data);
777 string serialized;
778 msg1.SerializeToString(&serialized);
779
780 // Test int64 is compatible with bool
781 unittest::BoolMessage msg2;
782 ASSERT_TRUE(msg2.ParseFromString(serialized));
783 ASSERT_EQ(static_cast<bool>(data), msg2.data());
784
785 // Test int64 is compatible with uint64
786 unittest::Uint64Message msg3;
787 ASSERT_TRUE(msg3.ParseFromString(serialized));
788 ASSERT_EQ(static_cast<uint64>(data), msg3.data());
789
790 // Test int64 is compatible with int32
791 unittest::Int32Message msg4;
792 ASSERT_TRUE(msg4.ParseFromString(serialized));
793 ASSERT_EQ(static_cast<int32>(data), msg4.data());
794
795 // Test int64 is compatible with uint32
796 unittest::Uint32Message msg5;
797 ASSERT_TRUE(msg5.ParseFromString(serialized));
798 ASSERT_EQ(static_cast<uint32>(data), msg5.data());
799}
800
Bo Yanga269a6d2015-06-15 16:54:02 -0700801class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test {
Bo Yang5db21732015-05-21 14:28:59 -0700802 protected:
Bo Yanga269a6d2015-06-15 16:54:02 -0700803 Proto3PrimitiveRepeatedWireFormatTest()
804 : packedTestAllTypes_(
805 "\xFA\x01\x01\x01"
806 "\x82\x02\x01\x01"
807 "\x8A\x02\x01\x01"
808 "\x92\x02\x01\x01"
809 "\x9A\x02\x01\x02"
810 "\xA2\x02\x01\x02"
811 "\xAA\x02\x04\x01\x00\x00\x00"
812 "\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
813 "\xBA\x02\x04\x01\x00\x00\x00"
814 "\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
815 "\xCA\x02\x04\x00\x00\x80\x3f"
816 "\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
817 "\xDA\x02\x01\x01"
818 "\x9A\x03\x01\x01",
819 86),
820 packedTestUnpackedTypes_(
821 "\x0A\x01\x01"
822 "\x12\x01\x01"
823 "\x1A\x01\x01"
824 "\x22\x01\x01"
825 "\x2A\x01\x02"
826 "\x32\x01\x02"
827 "\x3A\x04\x01\x00\x00\x00"
828 "\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00"
829 "\x4A\x04\x01\x00\x00\x00"
830 "\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00"
831 "\x5A\x04\x00\x00\x80\x3f"
832 "\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
833 "\x6A\x01\x01"
834 "\x72\x01\x01",
835 72),
836 unpackedTestAllTypes_(
837 "\xF8\x01\x01"
838 "\x80\x02\x01"
839 "\x88\x02\x01"
840 "\x90\x02\x01"
841 "\x98\x02\x02"
842 "\xA0\x02\x02"
843 "\xAD\x02\x01\x00\x00\x00"
844 "\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
845 "\xBD\x02\x01\x00\x00\x00"
846 "\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
847 "\xCD\x02\x00\x00\x80\x3f"
848 "\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f"
849 "\xD8\x02\x01"
850 "\x98\x03\x01",
851 72),
852 unpackedTestUnpackedTypes_(
853 "\x08\x01"
854 "\x10\x01"
855 "\x18\x01"
856 "\x20\x01"
857 "\x28\x02"
858 "\x30\x02"
859 "\x3D\x01\x00\x00\x00"
860 "\x41\x01\x00\x00\x00\x00\x00\x00\x00"
861 "\x4D\x01\x00\x00\x00"
862 "\x51\x01\x00\x00\x00\x00\x00\x00\x00"
863 "\x5D\x00\x00\x80\x3f"
864 "\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
865 "\x68\x01"
866 "\x70\x01",
867 58) {}
Bo Yang5db21732015-05-21 14:28:59 -0700868 template <class Proto>
869 void SetProto3PrimitiveRepeatedFields(Proto* message) {
870 message->add_repeated_int32(1);
871 message->add_repeated_int64(1);
872 message->add_repeated_uint32(1);
873 message->add_repeated_uint64(1);
874 message->add_repeated_sint32(1);
875 message->add_repeated_sint64(1);
876 message->add_repeated_fixed32(1);
877 message->add_repeated_fixed64(1);
878 message->add_repeated_sfixed32(1);
879 message->add_repeated_sfixed64(1);
880 message->add_repeated_float(1.0);
881 message->add_repeated_double(1.0);
882 message->add_repeated_bool(true);
883 message->add_repeated_nested_enum(
884 proto3_arena_unittest::TestAllTypes_NestedEnum_FOO);
885 }
886
887 template <class Proto>
888 void ExpectProto3PrimitiveRepeatedFieldsSet(const Proto& message) {
889 EXPECT_EQ(1, message.repeated_int32(0));
890 EXPECT_EQ(1, message.repeated_int64(0));
891 EXPECT_EQ(1, message.repeated_uint32(0));
892 EXPECT_EQ(1, message.repeated_uint64(0));
893 EXPECT_EQ(1, message.repeated_sint32(0));
894 EXPECT_EQ(1, message.repeated_sint64(0));
895 EXPECT_EQ(1, message.repeated_fixed32(0));
896 EXPECT_EQ(1, message.repeated_fixed64(0));
897 EXPECT_EQ(1, message.repeated_sfixed32(0));
898 EXPECT_EQ(1, message.repeated_sfixed64(0));
899 EXPECT_EQ(1.0, message.repeated_float(0));
900 EXPECT_EQ(1.0, message.repeated_double(0));
901 EXPECT_EQ(true, message.repeated_bool(0));
902 EXPECT_EQ(proto3_arena_unittest::TestAllTypes_NestedEnum_FOO,
903 message.repeated_nested_enum(0));
904 }
905
906 template <class Proto>
Bo Yanga269a6d2015-06-15 16:54:02 -0700907 void TestSerialization(Proto* message, const string& expected) {
Bo Yang5db21732015-05-21 14:28:59 -0700908 SetProto3PrimitiveRepeatedFields(message);
909
910 int size = message->ByteSize();
911
912 // Serialize using the generated code.
913 string generated_data;
914 {
915 io::StringOutputStream raw_output(&generated_data);
916 io::CodedOutputStream output(&raw_output);
917 message->SerializeWithCachedSizes(&output);
918 ASSERT_FALSE(output.HadError());
919 }
Bo Yang5db21732015-05-21 14:28:59 -0700920 EXPECT_TRUE(expected == generated_data);
921
Bo Yang5db21732015-05-21 14:28:59 -0700922 // Serialize using the dynamic code.
923 string dynamic_data;
924 {
925 io::StringOutputStream raw_output(&dynamic_data);
926 io::CodedOutputStream output(&raw_output);
927 WireFormat::SerializeWithCachedSizes(*message, size, &output);
928 ASSERT_FALSE(output.HadError());
929 }
Bo Yang5db21732015-05-21 14:28:59 -0700930 EXPECT_TRUE(expected == dynamic_data);
Bo Yanga269a6d2015-06-15 16:54:02 -0700931 }
932
933 template <class Proto>
934 void TestParsing(Proto* message, const string& compatible_data) {
935 message->Clear();
936 message->ParseFromString(compatible_data);
937 ExpectProto3PrimitiveRepeatedFieldsSet(*message);
Bo Yang5db21732015-05-21 14:28:59 -0700938
939 message->Clear();
940 io::CodedInputStream input(
Bo Yanga269a6d2015-06-15 16:54:02 -0700941 reinterpret_cast<const uint8*>(compatible_data.data()),
942 compatible_data.size());
Bo Yang5db21732015-05-21 14:28:59 -0700943 WireFormat::ParseAndMergePartial(&input, message);
944 ExpectProto3PrimitiveRepeatedFieldsSet(*message);
945 }
Bo Yang5db21732015-05-21 14:28:59 -0700946
Bo Yanga269a6d2015-06-15 16:54:02 -0700947 const string packedTestAllTypes_;
948 const string packedTestUnpackedTypes_;
949 const string unpackedTestAllTypes_;
950 const string unpackedTestUnpackedTypes_;
951};
952
953TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
Bo Yang5db21732015-05-21 14:28:59 -0700954 proto3_arena_unittest::TestAllTypes packed_message;
955 proto3_arena_unittest::TestUnpackedTypes unpacked_message;
Bo Yanga269a6d2015-06-15 16:54:02 -0700956 TestSerialization(&packed_message, packedTestAllTypes_);
957 TestParsing(&packed_message, packedTestAllTypes_);
958 TestParsing(&packed_message, unpackedTestAllTypes_);
959 TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_);
960 TestParsing(&unpacked_message, packedTestUnpackedTypes_);
961 TestParsing(&unpacked_message, unpackedTestUnpackedTypes_);
Bo Yang5db21732015-05-21 14:28:59 -0700962}
963
temporal40ee5512008-07-10 02:12:20 +0000964class WireFormatInvalidInputTest : public testing::Test {
965 protected:
966 // Make a serialized TestAllTypes in which the field optional_nested_message
967 // contains exactly the given bytes, which may be invalid.
968 string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
969 const FieldDescriptor* field =
970 unittest::TestAllTypes::descriptor()->FindFieldByName(
971 "optional_nested_message");
972 GOOGLE_CHECK(field != NULL);
973
974 string result;
975
976 {
977 io::StringOutputStream raw_output(&result);
978 io::CodedOutputStream output(&raw_output);
979
kenton@google.com80b1d622009-07-29 01:13:20 +0000980 WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output);
temporal40ee5512008-07-10 02:12:20 +0000981 }
982
983 return result;
984 }
985
986 // Make a serialized TestAllTypes in which the field optionalgroup
987 // contains exactly the given bytes -- which may be invalid -- and
988 // possibly no end tag.
989 string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) {
990 const FieldDescriptor* field =
991 unittest::TestAllTypes::descriptor()->FindFieldByName(
992 "optionalgroup");
993 GOOGLE_CHECK(field != NULL);
994
995 string result;
996
997 {
998 io::StringOutputStream raw_output(&result);
999 io::CodedOutputStream output(&raw_output);
1000
kenton@google.comd37d46d2009-04-25 02:53:47 +00001001 output.WriteVarint32(WireFormat::MakeTag(field));
1002 output.WriteString(string(bytes, size));
temporal40ee5512008-07-10 02:12:20 +00001003 if (include_end_tag) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001004 output.WriteVarint32(WireFormatLite::MakeTag(
1005 field->number(), WireFormatLite::WIRETYPE_END_GROUP));
temporal40ee5512008-07-10 02:12:20 +00001006 }
1007 }
1008
1009 return result;
1010 }
1011};
1012
1013TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
1014 unittest::TestAllTypes message;
1015
1016 // Control case.
1017 EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
1018
1019 // The byte is a valid varint, but not a valid tag (zero).
1020 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
1021
1022 // The byte is a malformed varint.
1023 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
1024
1025 // The byte is an endgroup tag, but we aren't parsing a group.
1026 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
1027
1028 // The byte is a valid varint but not a valid tag (bad wire type).
1029 EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
1030}
1031
1032TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
1033 unittest::TestAllTypes message;
1034
1035 // Control case.
1036 EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
1037
1038 // Missing end tag. Groups cannot end at EOF.
1039 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
1040
1041 // The byte is a valid varint, but not a valid tag (zero).
1042 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
1043
1044 // The byte is a malformed varint.
1045 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
1046
1047 // The byte is an endgroup tag, but not the right one for this group.
1048 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
1049
1050 // The byte is a valid varint but not a valid tag (bad wire type).
1051 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
1052}
1053
1054TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
temporal779f61c2008-08-13 03:15:00 +00001055 // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
temporal40ee5512008-07-10 02:12:20 +00001056 // be a known tag number.
temporal779f61c2008-08-13 03:15:00 +00001057 unittest::TestEmptyMessage message;
temporal40ee5512008-07-10 02:12:20 +00001058
1059 // Control case.
1060 EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
1061
1062 // Missing end tag. Groups cannot end at EOF.
1063 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
1064
1065 // The byte is a valid varint, but not a valid tag (zero).
1066 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
1067
1068 // The byte is a malformed varint.
1069 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
1070
1071 // The byte is an endgroup tag, but not the right one for this group.
1072 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
1073
1074 // The byte is a valid varint but not a valid tag (bad wire type).
1075 EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
1076}
1077
temporal779f61c2008-08-13 03:15:00 +00001078TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
1079 // Test a bug fix: SkipMessage should fail if the message contains a string
1080 // whose length would extend beyond the message end.
1081
1082 unittest::TestAllTypes message;
1083 message.set_optional_string("foo foo foo foo");
1084 string data;
1085 message.SerializeToString(&data);
1086
1087 // Chop some bytes off the end.
1088 data.resize(data.size() - 4);
1089
1090 // Try to skip it. Note that the bug was only present when parsing to an
1091 // UnknownFieldSet.
1092 io::ArrayInputStream raw_input(data.data(), data.size());
1093 io::CodedInputStream coded_input(&raw_input);
1094 UnknownFieldSet unknown_fields;
1095 EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
1096}
1097
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001098// Test differences between string and bytes.
1099// Value of a string type must be valid UTF-8 string. When UTF-8
1100// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
1101// WriteInvalidUTF8String: see error message.
1102// ReadInvalidUTF8String: see error message.
1103// WriteValidUTF8String: fine.
1104// ReadValidUTF8String: fine.
1105// WriteAnyBytes: fine.
1106// ReadAnyBytes: fine.
1107const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
kenton@google.com503a4dd2009-04-28 02:16:53 +00001108// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
1109// interpret \u differently from GCC.
1110const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001111
1112template<typename T>
1113bool WriteMessage(const char *value, T *message, string *wire_buffer) {
1114 message->set_data(value);
1115 wire_buffer->clear();
1116 message->AppendToString(wire_buffer);
1117 return (wire_buffer->size() > 0);
1118}
1119
1120template<typename T>
1121bool ReadMessage(const string &wire_buffer, T *message) {
1122 return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
1123}
1124
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001125bool StartsWith(const string& s, const string& prefix) {
1126 return s.substr(0, prefix.length()) == prefix;
1127}
1128
jieluo@google.com4de8f552014-07-18 00:47:59 +00001129class Utf8ValidationTest : public ::testing::Test {
1130 protected:
1131 Utf8ValidationTest() {}
1132 virtual ~Utf8ValidationTest() {}
1133 virtual void SetUp() {
1134 }
1135
1136};
1137
1138TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001139 string wire_buffer;
1140 protobuf_unittest::OneString input;
1141 vector<string> errors;
1142 {
1143 ScopedMemoryLog log;
1144 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1145 errors = log.GetMessages(ERROR);
1146 }
1147#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1148 ASSERT_EQ(1, errors.size());
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001149 EXPECT_TRUE(StartsWith(errors[0],
Feng Xiao6ef984a2014-11-10 17:34:54 -08001150 "String field 'protobuf_unittest.OneString.data' "
1151 "contains invalid UTF-8 data when "
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001152 "serializing a protocol buffer. Use the "
1153 "'bytes' type if you intend to send raw bytes."));
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001154#else
1155 ASSERT_EQ(0, errors.size());
1156#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1157}
1158
jieluo@google.com4de8f552014-07-18 00:47:59 +00001159
1160TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001161 string wire_buffer;
1162 protobuf_unittest::OneString input;
1163 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1164 protobuf_unittest::OneString output;
1165 vector<string> errors;
1166 {
1167 ScopedMemoryLog log;
1168 ReadMessage(wire_buffer, &output);
1169 errors = log.GetMessages(ERROR);
1170 }
1171#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1172 ASSERT_EQ(1, errors.size());
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001173 EXPECT_TRUE(StartsWith(errors[0],
Feng Xiao6ef984a2014-11-10 17:34:54 -08001174 "String field 'protobuf_unittest.OneString.data' "
1175 "contains invalid UTF-8 data when "
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001176 "parsing a protocol buffer. Use the "
1177 "'bytes' type if you intend to send raw bytes."));
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001178
1179#else
1180 ASSERT_EQ(0, errors.size());
1181#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1182}
1183
jieluo@google.com4de8f552014-07-18 00:47:59 +00001184
1185TEST_F(Utf8ValidationTest, WriteValidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001186 string wire_buffer;
1187 protobuf_unittest::OneString input;
1188 vector<string> errors;
1189 {
1190 ScopedMemoryLog log;
1191 WriteMessage(kValidUTF8String, &input, &wire_buffer);
1192 errors = log.GetMessages(ERROR);
1193 }
1194 ASSERT_EQ(0, errors.size());
1195}
1196
jieluo@google.com4de8f552014-07-18 00:47:59 +00001197TEST_F(Utf8ValidationTest, ReadValidUTF8String) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001198 string wire_buffer;
1199 protobuf_unittest::OneString input;
1200 WriteMessage(kValidUTF8String, &input, &wire_buffer);
1201 protobuf_unittest::OneString output;
1202 vector<string> errors;
1203 {
1204 ScopedMemoryLog log;
1205 ReadMessage(wire_buffer, &output);
1206 errors = log.GetMessages(ERROR);
1207 }
1208 ASSERT_EQ(0, errors.size());
1209 EXPECT_EQ(input.data(), output.data());
1210}
1211
1212// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
jieluo@google.com4de8f552014-07-18 00:47:59 +00001213TEST_F(Utf8ValidationTest, WriteArbitraryBytes) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001214 string wire_buffer;
1215 protobuf_unittest::OneBytes input;
1216 vector<string> errors;
1217 {
1218 ScopedMemoryLog log;
1219 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1220 errors = log.GetMessages(ERROR);
1221 }
1222 ASSERT_EQ(0, errors.size());
1223}
1224
jieluo@google.com4de8f552014-07-18 00:47:59 +00001225TEST_F(Utf8ValidationTest, ReadArbitraryBytes) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +00001226 string wire_buffer;
1227 protobuf_unittest::OneBytes input;
1228 WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
1229 protobuf_unittest::OneBytes output;
1230 vector<string> errors;
1231 {
1232 ScopedMemoryLog log;
1233 ReadMessage(wire_buffer, &output);
1234 errors = log.GetMessages(ERROR);
1235 }
1236 ASSERT_EQ(0, errors.size());
1237 EXPECT_EQ(input.data(), output.data());
1238}
1239
jieluo@google.com4de8f552014-07-18 00:47:59 +00001240TEST_F(Utf8ValidationTest, ParseRepeatedString) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001241 protobuf_unittest::MoreBytes input;
1242 input.add_data(kValidUTF8String);
1243 input.add_data(kInvalidUTF8String);
1244 input.add_data(kInvalidUTF8String);
1245 string wire_buffer = input.SerializeAsString();
1246
1247 protobuf_unittest::MoreString output;
1248 vector<string> errors;
1249 {
1250 ScopedMemoryLog log;
1251 ReadMessage(wire_buffer, &output);
1252 errors = log.GetMessages(ERROR);
1253 }
1254#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1255 ASSERT_EQ(2, errors.size());
1256#else
1257 ASSERT_EQ(0, errors.size());
1258#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1259 EXPECT_EQ(wire_buffer, output.SerializeAsString());
1260}
1261
jieluo@google.com4de8f552014-07-18 00:47:59 +00001262// Test the old VerifyUTF8String() function, which may still be called by old
1263// generated code.
1264TEST_F(Utf8ValidationTest, OldVerifyUTF8String) {
1265 string data(kInvalidUTF8String);
1266
1267 vector<string> errors;
1268 {
1269 ScopedMemoryLog log;
1270 WireFormat::VerifyUTF8String(data.data(), data.size(),
1271 WireFormat::SERIALIZE);
1272 errors = log.GetMessages(ERROR);
1273 }
1274#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
1275 ASSERT_EQ(1, errors.size());
1276 EXPECT_TRUE(StartsWith(errors[0],
1277 "String field contains invalid UTF-8 data when "
1278 "serializing a protocol buffer. Use the "
1279 "'bytes' type if you intend to send raw bytes."));
1280#else
1281 ASSERT_EQ(0, errors.size());
1282#endif
1283}
1284
1285
temporal40ee5512008-07-10 02:12:20 +00001286} // namespace
1287} // namespace internal
1288} // namespace protobuf
1289} // namespace google