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