15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format_lite_inl.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unittest.pb.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unittest_mset.pb.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/test_util.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/stl_util.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, EnumsInSync) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FieldDescriptor::Type and FieldDescriptor::CppType.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      implicit_cast<int>(FieldDescriptor::TypeToCppType(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<FieldDescriptor::Type>(i))),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<WireFormatLite::FieldType>(i))));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, MaxFieldNumber) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the max field number constant is accurate.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FieldDescriptor::kMaxNumber);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, Parse) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes source, dest;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFields(&source);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source.SerializeToString(&data);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllFieldsSet(dest);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParseExtensions) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllExtensions source, dest;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllExtensions(&source);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source.SerializeToString(&data);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllExtensionsSet(dest);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParsePacked) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedTypes source, dest;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetPackedFields(&source);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source.SerializeToString(&data);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectPackedFieldsSet(dest);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParsePackedFromUnpacked) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestUnpackedTypes source;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetUnpackedFields(&source);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data = source.SerializeAsString();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedTypes dest;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectPackedFieldsSet(dest);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParseUnpackedFromPacked) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedTypes source;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetPackedFields(&source);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data = source.SerializeAsString();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestUnpackedTypes dest;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectUnpackedFieldsSet(dest);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParsePackedExtensions) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedExtensions source, dest;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetPackedExtensions(&source);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source.SerializeToString(&data);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse using WireFormat.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(&raw_input);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormat::ParseAndMergePartial(&input, &dest);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectPackedExtensionsSet(dest);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ByteSize) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFields(&message);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.Clear();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, message.ByteSize());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, WireFormat::ByteSize(message));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ByteSizeExtensions) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllExtensions message;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllExtensions(&message);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.ByteSize(),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            WireFormat::ByteSize(message));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.Clear();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, message.ByteSize());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, WireFormat::ByteSize(message));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ByteSizePacked) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedTypes message;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetPackedFields(&message);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.Clear();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, message.ByteSize());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, WireFormat::ByteSize(message));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ByteSizePackedExtensions) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestPackedExtensions message;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetPackedExtensions(&message);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message.ByteSize(),
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            WireFormat::ByteSize(message));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.Clear();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, message.ByteSize());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, WireFormat::ByteSize(message));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, Serialize) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string generated_data;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string dynamic_data;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFields(&message);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = message.ByteSize();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&generated_data);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.SerializeWithCachedSizes(&output);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using WireFormat.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&dynamic_data);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormat::SerializeWithCachedSizes(message, size, &output);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be the same.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't use EXPECT_EQ here because we're comparing raw binary data and
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we really don't want it dumped to stdout on failure.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(dynamic_data == generated_data);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, SerializeExtensions) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllExtensions message;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string generated_data;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string dynamic_data;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllExtensions(&message);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = message.ByteSize();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&generated_data);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.SerializeWithCachedSizes(&output);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using WireFormat.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&dynamic_data);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormat::SerializeWithCachedSizes(message, size, &output);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be the same.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't use EXPECT_EQ here because we're comparing raw binary data and
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we really don't want it dumped to stdout on failure.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(dynamic_data == generated_data);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, SerializeFieldsAndExtensions) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestFieldOrderings message;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string generated_data;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string dynamic_data;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFieldsAndExtensions(&message);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = message.ByteSize();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using the generated code.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&generated_data);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.SerializeWithCachedSizes(&output);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize using WireFormat.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream raw_output(&dynamic_data);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output(&raw_output);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormat::SerializeWithCachedSizes(message, size, &output);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output.HadError());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be the same.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't use EXPECT_EQ here because we're comparing raw binary data and
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we really don't want it dumped to stdout on failure.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(dynamic_data == generated_data);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should output in canonical order.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParseMultipleExtensionRanges) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we can parse a message that contains multiple extensions ranges.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestFieldOrderings source;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUtil::SetAllFieldsAndExtensions(&source);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source.SerializeToString(&data);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestFieldOrderings dest;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(dest.ParseFromString(data));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(source.DebugString(), dest.DebugString());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also test using reflection-based parsing.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestFieldOrderings dest;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayInputStream raw_input(data.data(), data.size());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream coded_input(&raw_input);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(source.DebugString(), dest.DebugString());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kUnknownTypeId = 1550055;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, SerializeMessageSet) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a TestMessageSet with two known messages and an unknown one.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSet message_set;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.MutableExtension(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.MutableExtension(
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.mutable_unknown_fields()->AddLengthDelimited(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUnknownTypeId, "bar");
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message_set.SerializeToString(&data));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse back using RawMessageSet and check the contents.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::RawMessageSet raw;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(raw.ParseFromString(data));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, raw.unknown_fields().field_count());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, raw.item_size());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(),
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    raw.item(0).type_id());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(),
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    raw.item(1).type_id());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSetExtension1 message1;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123, message1.i());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSetExtension2 message2;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", message2.str());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar", raw.item(2).message());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize a MessageSet to a stream and to a flat array using generated
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // code, and also using WireFormat, and check that the results are equal.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a TestMessageSet with two known messages and an unknown one, as
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // above.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSet message_set;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.MutableExtension(
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.MutableExtension(
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_set.mutable_unknown_fields()->AddLengthDelimited(
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUnknownTypeId, "bar");
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = message_set.ByteSize();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(size, message_set.GetCachedSize());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(size, WireFormat::ByteSize(message_set));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string flat_data;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string stream_data;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string dynamic_data;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  flat_data.resize(size);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stream_data.resize(size);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize to flat array
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8* end = message_set.SerializeWithCachedSizesToArray(target);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(size, end - target);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize to buffer
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output_stream(&array_stream);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_set.SerializeWithCachedSizes(&output_stream);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output_stream.HadError());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialize to buffer with WireFormat.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::StringOutputStream string_stream(&dynamic_data);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream output_stream(&string_stream);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(output_stream.HadError());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(flat_data == stream_data);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(flat_data == dynamic_data);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ParseMessageSet) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a RawMessageSet with two known messages and an unknown one.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::RawMessageSet raw;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::RawMessageSet::Item* item = raw.add_item();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->set_type_id(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unittest::TestMessageSetExtension1::descriptor()->extension(0)->number());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension1 message;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.set_i(123);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.SerializeToString(item->mutable_message());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::RawMessageSet::Item* item = raw.add_item();
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->set_type_id(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unittest::TestMessageSetExtension2::descriptor()->extension(0)->number());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension2 message;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.set_str("foo");
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message.SerializeToString(item->mutable_message());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::RawMessageSet::Item* item = raw.add_item();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->set_type_id(kUnknownTypeId);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->set_message("bar");
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(raw.SerializeToString(&data));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse as a TestMessageSet and check the contents.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSet message_set;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message_set.ParseFromString(data));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123, message_set.GetExtension(
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension1::message_set_extension).i());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", message_set.GetExtension(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestMessageSetExtension2::message_set_extension).str());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, message_set.unknown_fields().field_count());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_set.unknown_fields().field(0).type());
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also parse using WireFormat.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestMessageSet dynamic_message_set;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             data.size());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
484ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  string data;
485ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
486ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    unittest::TestMessageSetExtension1 message;
487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    message.set_i(123);
488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Build a MessageSet manually with its message content put before its
489ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // type_id.
490ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    io::StringOutputStream output_stream(&data);
491ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    io::CodedOutputStream coded_output(&output_stream);
492ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
493ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Write the message content first.
494ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
495ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
496ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             &coded_output);
497ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    coded_output.WriteVarint32(message.ByteSize());
498ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    message.SerializeWithCachedSizes(&coded_output);
499ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Write the type id.
500ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint32 type_id = message.GetDescriptor()->extension(0)->number();
501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                type_id, &coded_output);
503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    unittest::TestMessageSet message_set;
507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ASSERT_TRUE(message_set.ParseFromString(data));
508ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_EQ(123, message_set.GetExtension(
510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        unittest::TestMessageSetExtension1::message_set_extension).i());
511ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
512ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
513ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Test parse the message via Reflection.
514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    unittest::TestMessageSet message_set;
515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    io::CodedInputStream input(
516ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        reinterpret_cast<const uint8*>(data.data()), data.size());
517ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
518ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_TRUE(input.ConsumedEntireMessage());
519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
520ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_EQ(123, message_set.GetExtension(
521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        unittest::TestMessageSetExtension1::message_set_extension).i());
522ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST(WireFormatTest, ParseBrokenMessageSet) {
526ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  unittest::TestMessageSet message_set;
527ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  string input("goodbye");  // Invalid wire format data.
528ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(message_set.ParseFromString(input));
529ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
530ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, RecursionLimit) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestRecursiveMessage message;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.SerializeToString(&data);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayInputStream raw_input(data.data(), data.size());
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream input(&raw_input);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input.SetRecursionLimit(4);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestRecursiveMessage message2;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(message2.ParseFromCodedStream(&input));
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayInputStream raw_input(data.data(), data.size());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream input(&raw_input);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input.SetRecursionLimit(3);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestRecursiveMessage message2;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(message2.ParseFromCodedStream(&input));
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, UnknownFieldRecursionLimit) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestEmptyMessage message;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.mutable_unknown_fields()
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ->AddGroup(1234)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ->AddGroup(1234)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ->AddGroup(1234)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ->AddGroup(1234)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ->AddVarint(1234, 123);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.SerializeToString(&data);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayInputStream raw_input(data.data(), data.size());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream input(&raw_input);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input.SetRecursionLimit(4);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestEmptyMessage message2;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(message2.ParseFromCodedStream(&input));
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::ArrayInputStream raw_input(data.data(), data.size());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream input(&raw_input);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input.SetRecursionLimit(3);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unittest::TestEmptyMessage message2;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(message2.ParseFromCodedStream(&input));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, ZigZag) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoid line-wrapping
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LL(x) GOOGLE_LONGLONG(x)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ULL(x) GOOGLE_ULONGLONG(x)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, ZigZagEncode32( 0));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ZigZagEncode32(-1));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, ZigZagEncode32( 1));
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, ZigZagEncode32(-2));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ( 0, ZigZagDecode32(0u));
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, ZigZagDecode32(1u));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ( 1, ZigZagDecode32(2u));
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2, ZigZagDecode32(3u));
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, ZigZagEncode64( 0));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ZigZagEncode64(-1));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, ZigZagEncode64( 1));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, ZigZagEncode64(-2));
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ( 0, ZigZagDecode64(0u));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, ZigZagDecode64(1u));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ( 1, ZigZagDecode64(2u));
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-2, ZigZagDecode64(3u));
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // were chosen semi-randomly via keyboard bashing.
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(    0, ZigZagDecode32(ZigZagEncode32(    0)));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(    1, ZigZagDecode32(ZigZagEncode32(    1)));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(   -1, ZigZagDecode32(ZigZagEncode32(   -1)));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(    0, ZigZagDecode64(ZigZagEncode64(    0)));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(    1, ZigZagDecode64(ZigZagEncode64(    1)));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(   -1, ZigZagDecode64(ZigZagEncode64(   -1)));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64(
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LL(856912304801416))));
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64(
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            LL(-75123905439571256))));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At one point checks would trigger when parsing repeated fixed scalar
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fields.
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 100; ++i) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_fixed32(i);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_int32(i);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_fixed64(i);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_int64(i);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_float(i);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg1.add_repeated_uint64(i);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that we have a variety of tag sizes.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const google::protobuf::FieldDescriptor* field;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_fixed32");
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_int32");
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_fixed64");
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_int64");
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_float");
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  field = desc->FindFieldByName("repeated_uint64");
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(field != NULL);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WireFormatInvalidInputTest : public testing::Test {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a serialized TestAllTypes in which the field optional_nested_message
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contains exactly the given bytes, which may be invalid.
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldDescriptor* field =
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unittest::TestAllTypes::descriptor()->FindFieldByName(
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "optional_nested_message");
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_CHECK(field != NULL);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string result;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io::StringOutputStream raw_output(&result);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io::CodedOutputStream output(&raw_output);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a serialized TestAllTypes in which the field optionalgroup
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contains exactly the given bytes -- which may be invalid -- and
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possibly no end tag.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FieldDescriptor* field =
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unittest::TestAllTypes::descriptor()->FindFieldByName(
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "optionalgroup");
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_CHECK(field != NULL);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string result;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io::StringOutputStream raw_output(&result);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io::CodedOutputStream output(&raw_output);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output.WriteVarint32(WireFormat::MakeTag(field));
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output.WriteString(string(bytes, size));
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (include_end_tag) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output.WriteVarint32(WireFormatLite::MakeTag(
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          field->number(), WireFormatLite::WIRETYPE_END_GROUP));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Control case.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint, but not a valid tag (zero).
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a malformed varint.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is an endgroup tag, but we aren't parsing a group.
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint but not a valid tag (bad wire type).
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Control case.
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Missing end tag.  Groups cannot end at EOF.
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint, but not a valid tag (zero).
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a malformed varint.
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is an endgroup tag, but not the right one for this group.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint but not a valid tag (bad wire type).
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be a known tag number.
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestEmptyMessage message;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Control case.
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Missing end tag.  Groups cannot end at EOF.
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint, but not a valid tag (zero).
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a malformed varint.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is an endgroup tag, but not the right one for this group.
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The byte is a valid varint but not a valid tag (bad wire type).
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a bug fix:  SkipMessage should fail if the message contains a string
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whose length would extend beyond the message end.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest::TestAllTypes message;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.set_optional_string("foo foo foo foo");
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string data;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.SerializeToString(&data);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chop some bytes off the end.
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.resize(data.size() - 4);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to skip it.  Note that the bug was only present when parsing to an
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UnknownFieldSet.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::ArrayInputStream raw_input(data.data(), data.size());
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io::CodedInputStream coded_input(&raw_input);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnknownFieldSet unknown_fields;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test differences between string and bytes.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Value of a string type must be valid UTF-8 string.  When UTF-8
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WriteInvalidUTF8String:  see error message.
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReadInvalidUTF8String:  see error message.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WriteValidUTF8String: fine.
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReadValidUTF8String:  fine.
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WriteAnyBytes: fine.
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReadAnyBytes: fine.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interpret \u differently from GCC.
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WriteMessage(const char *value, T *message, string *wire_buffer) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message->set_data(value);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wire_buffer->clear();
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message->AppendToString(wire_buffer);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (wire_buffer->size() > 0);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReadMessage(const string &wire_buffer, T *message) {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
851ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool StartsWith(const string& s, const string& prefix) {
852ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return s.substr(0, prefix.length()) == prefix;
853ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
854ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, WriteInvalidUTF8String) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString input;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, errors.size());
866ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(StartsWith(errors[0],
867ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "String field contains invalid UTF-8 data when "
868ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "serializing a protocol buffer. Use the "
869ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "'bytes' type if you intend to send raw bytes."));
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, ReadInvalidUTF8String) {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString input;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString output;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadMessage(wire_buffer, &output);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, errors.size());
888ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(StartsWith(errors[0],
889ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "String field contains invalid UTF-8 data when "
890ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "parsing a protocol buffer. Use the "
891ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         "'bytes' type if you intend to send raw bytes."));
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, WriteValidUTF8String) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString input;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteMessage(kValidUTF8String, &input, &wire_buffer);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, ReadValidUTF8String) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString input;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WriteMessage(kValidUTF8String, &input, &wire_buffer);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneString output;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadMessage(wire_buffer, &output);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(input.data(), output.data());
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, WriteArbitraryBytes) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneBytes input;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Utf8ValidationTest, ReadArbitraryBytes) {
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string wire_buffer;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneBytes input;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::OneBytes output;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadMessage(wire_buffer, &output);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, errors.size());
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(input.data(), output.data());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
953ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST(Utf8ValidationTest, ParseRepeatedString) {
954ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  protobuf_unittest::MoreBytes input;
955ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  input.add_data(kValidUTF8String);
956ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  input.add_data(kInvalidUTF8String);
957ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  input.add_data(kInvalidUTF8String);
958ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  string wire_buffer = input.SerializeAsString();
959ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
960ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  protobuf_unittest::MoreString output;
961ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  vector<string> errors;
962ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
963ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ScopedMemoryLog log;
964ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ReadMessage(wire_buffer, &output);
965ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    errors = log.GetMessages(ERROR);
966ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
967ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
968ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(2, errors.size());
969ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#else
970ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(0, errors.size());
971ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
972ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(wire_buffer, output.SerializeAsString());
973ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
974ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
979