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 contains tests and benchmarks.
36
37#include <vector>
38
39#include <google/protobuf/io/coded_stream.h>
40
41#include <limits.h>
42
43#include <google/protobuf/stubs/common.h>
44#include <google/protobuf/testing/googletest.h>
45#include <gtest/gtest.h>
46#include <google/protobuf/io/zero_copy_stream_impl.h>
47
48
49// This declares an unsigned long long integer literal in a portable way.
50// (The original macro is way too big and ruins my formatting.)
51#undef ULL
52#define ULL(x) GOOGLE_ULONGLONG(x)
53
54namespace google {
55namespace protobuf {
56namespace io {
57namespace {
58
59// ===================================================================
60// Data-Driven Test Infrastructure
61
62// TEST_1D and TEST_2D are macros I'd eventually like to see added to
63// gTest.  These macros can be used to declare tests which should be
64// run multiple times, once for each item in some input array.  TEST_1D
65// tests all cases in a single input array.  TEST_2D tests all
66// combinations of cases from two arrays.  The arrays must be statically
67// defined such that the GOOGLE_ARRAYSIZE() macro works on them.  Example:
68//
69// int kCases[] = {1, 2, 3, 4}
70// TEST_1D(MyFixture, MyTest, kCases) {
71//   EXPECT_GT(kCases_case, 0);
72// }
73//
74// This test iterates through the numbers 1, 2, 3, and 4 and tests that
75// they are all grater than zero.  In case of failure, the exact case
76// which failed will be printed.  The case type must be printable using
77// ostream::operator<<.
78
79// TODO(kenton):  gTest now supports "parameterized tests" which would be
80//   a better way to accomplish this.  Rewrite when time permits.
81
82#define TEST_1D(FIXTURE, NAME, CASES)                                      \
83  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
84   protected:                                                              \
85    template <typename CaseType>                                           \
86    void DoSingleCase(const CaseType& CASES##_case);                       \
87  };                                                                       \
88                                                                           \
89  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
90    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) {                           \
91      SCOPED_TRACE(testing::Message()                                      \
92        << #CASES " case #" << i << ": " << CASES[i]);                     \
93      DoSingleCase(CASES[i]);                                              \
94    }                                                                      \
95  }                                                                        \
96                                                                           \
97  template <typename CaseType>                                             \
98  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
99
100#define TEST_2D(FIXTURE, NAME, CASES1, CASES2)                             \
101  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
102   protected:                                                              \
103    template <typename CaseType1, typename CaseType2>                      \
104    void DoSingleCase(const CaseType1& CASES1##_case,                      \
105                      const CaseType2& CASES2##_case);                     \
106  };                                                                       \
107                                                                           \
108  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
109    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) {                          \
110      for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) {                        \
111        SCOPED_TRACE(testing::Message()                                    \
112          << #CASES1 " case #" << i << ": " << CASES1[i] << ", "           \
113          << #CASES2 " case #" << j << ": " << CASES2[j]);                 \
114        DoSingleCase(CASES1[i], CASES2[j]);                                \
115      }                                                                    \
116    }                                                                      \
117  }                                                                        \
118                                                                           \
119  template <typename CaseType1, typename CaseType2>                        \
120  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
121                                           const CaseType2& CASES2##_case)
122
123// ===================================================================
124
125class CodedStreamTest : public testing::Test {
126 protected:
127  // Helper method used by tests for bytes warning. See implementation comment
128  // for further information.
129  static void SetupTotalBytesLimitWarningTest(
130      int total_bytes_limit, int warning_threshold,
131      vector<string>* out_errors, vector<string>* out_warnings);
132
133  // Buffer used during most of the tests. This assumes tests run sequentially.
134  static const int kBufferSize = 1024 * 64;
135  static uint8 buffer_[kBufferSize];
136};
137
138uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
139
140// We test each operation over a variety of block sizes to insure that
141// we test cases where reads or writes cross buffer boundaries, cases
142// where they don't, and cases where there is so much buffer left that
143// we can use special optimized paths that don't worry about bounds
144// checks.
145const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
146
147// -------------------------------------------------------------------
148// Varint tests.
149
150struct VarintCase {
151  uint8 bytes[10];          // Encoded bytes.
152  int size;                 // Encoded size, in bytes.
153  uint64 value;             // Parsed value.
154};
155
156inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
157  return os << c.value;
158}
159
160VarintCase kVarintCases[] = {
161  // 32-bit values
162  {{0x00}      , 1, 0},
163  {{0x01}      , 1, 1},
164  {{0x7f}      , 1, 127},
165  {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)},          // 14882
166  {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5,                    // 2961488830
167    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
168    (ULL(0x0b) << 28)},
169
170  // 64-bit
171  {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5,                    // 7256456126
172    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
173    (ULL(0x1b) << 28)},
174  {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8,  // 41256202580718336
175    (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
176    (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
177    (ULL(0x49) << 49)},
178  // 11964378330978735131
179  {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
180    (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
181    (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
182    (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
183};
184
185TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
186  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
187  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
188
189  {
190    CodedInputStream coded_input(&input);
191
192    uint32 value;
193    EXPECT_TRUE(coded_input.ReadVarint32(&value));
194    EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
195  }
196
197  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
198}
199
200TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
201  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
202  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
203
204  {
205    CodedInputStream coded_input(&input);
206
207    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
208    EXPECT_EQ(expected_value, coded_input.ReadTag());
209
210    EXPECT_TRUE(coded_input.LastTagWas(expected_value));
211    EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
212  }
213
214  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
215}
216
217// This is the regression test that verifies that there is no issues
218// with the empty input buffers handling.
219TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
220  class In : public ZeroCopyInputStream {
221   public:
222    In() : count_(0) {}
223   private:
224    virtual bool Next(const void** data, int* size) {
225      *data = NULL;
226      *size = 0;
227      return count_++ < 2;
228    }
229    virtual void BackUp(int count)  {
230      GOOGLE_LOG(FATAL) << "Tests never call this.";
231    }
232    virtual bool Skip(int count) {
233      GOOGLE_LOG(FATAL) << "Tests never call this.";
234      return false;
235    }
236    virtual int64 ByteCount() const { return 0; }
237    int count_;
238  } in;
239  CodedInputStream input(&in);
240  input.ReadTag();
241  EXPECT_TRUE(input.ConsumedEntireMessage());
242}
243
244TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
245  // Leave one byte at the beginning of the buffer so we can read it
246  // to force the first buffer to be loaded.
247  buffer_[0] = '\0';
248  memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
249  ArrayInputStream input(buffer_, sizeof(buffer_));
250
251  {
252    CodedInputStream coded_input(&input);
253
254    // Read one byte to force coded_input.Refill() to be called.  Otherwise,
255    // ExpectTag() will return a false negative.
256    uint8 dummy;
257    coded_input.ReadRaw(&dummy, 1);
258    EXPECT_EQ((uint)'\0', (uint)dummy);
259
260    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
261
262    // ExpectTag() produces false negatives for large values.
263    if (kVarintCases_case.size <= 2) {
264      EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
265      EXPECT_TRUE(coded_input.ExpectTag(expected_value));
266    } else {
267      EXPECT_FALSE(coded_input.ExpectTag(expected_value));
268    }
269  }
270
271  if (kVarintCases_case.size <= 2) {
272    EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
273  } else {
274    EXPECT_EQ(1, input.ByteCount());
275  }
276}
277
278TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
279  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
280
281  const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
282
283  // If the expectation succeeds, it should return a pointer past the tag.
284  if (kVarintCases_case.size <= 2) {
285    EXPECT_TRUE(NULL ==
286                CodedInputStream::ExpectTagFromArray(buffer_,
287                                                     expected_value + 1));
288    EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
289                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
290  } else {
291    EXPECT_TRUE(NULL ==
292                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
293  }
294}
295
296TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
297  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
298  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
299
300  {
301    CodedInputStream coded_input(&input);
302
303    uint64 value;
304    EXPECT_TRUE(coded_input.ReadVarint64(&value));
305    EXPECT_EQ(kVarintCases_case.value, value);
306  }
307
308  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
309}
310
311TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
312  if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
313    // Skip this test for the 64-bit values.
314    return;
315  }
316
317  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
318
319  {
320    CodedOutputStream coded_output(&output);
321
322    coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
323    EXPECT_FALSE(coded_output.HadError());
324
325    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
326  }
327
328  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
329  EXPECT_EQ(0,
330    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
331}
332
333TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
334  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
335
336  {
337    CodedOutputStream coded_output(&output);
338
339    coded_output.WriteVarint64(kVarintCases_case.value);
340    EXPECT_FALSE(coded_output.HadError());
341
342    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
343  }
344
345  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
346  EXPECT_EQ(0,
347    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
348}
349
350// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
351//   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
352#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
353
354int32 kSignExtendedVarintCases[] = {
355  0, 1, -1, 1237894, -37895138
356};
357
358TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
359        kSignExtendedVarintCases, kBlockSizes) {
360  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
361
362  {
363    CodedOutputStream coded_output(&output);
364
365    coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
366    EXPECT_FALSE(coded_output.HadError());
367
368    if (kSignExtendedVarintCases_case < 0) {
369      EXPECT_EQ(10, coded_output.ByteCount());
370    } else {
371      EXPECT_LE(coded_output.ByteCount(), 5);
372    }
373  }
374
375  if (kSignExtendedVarintCases_case < 0) {
376    EXPECT_EQ(10, output.ByteCount());
377  } else {
378    EXPECT_LE(output.ByteCount(), 5);
379  }
380
381  // Read value back in as a varint64 and insure it matches.
382  ArrayInputStream input(buffer_, sizeof(buffer_));
383
384  {
385    CodedInputStream coded_input(&input);
386
387    uint64 value;
388    EXPECT_TRUE(coded_input.ReadVarint64(&value));
389
390    EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
391  }
392
393  EXPECT_EQ(output.ByteCount(), input.ByteCount());
394}
395
396#endif
397
398
399// -------------------------------------------------------------------
400// Varint failure test.
401
402struct VarintErrorCase {
403  uint8 bytes[12];
404  int size;
405  bool can_parse;
406};
407
408inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
409  return os << "size " << c.size;
410}
411
412const VarintErrorCase kVarintErrorCases[] = {
413  // Control case.  (Insures that there isn't something else wrong that
414  // makes parsing always fail.)
415  {{0x00}, 1, true},
416
417  // No input data.
418  {{}, 0, false},
419
420  // Input ends unexpectedly.
421  {{0xf0, 0xab}, 2, false},
422
423  // Input ends unexpectedly after 32 bits.
424  {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
425
426  // Longer than 10 bytes.
427  {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
428   11, false},
429};
430
431TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
432  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
433  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
434                         kBlockSizes_case);
435  CodedInputStream coded_input(&input);
436
437  uint32 value;
438  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
439}
440
441TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
442  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
443  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
444                         kBlockSizes_case);
445  CodedInputStream coded_input(&input);
446
447  uint64 value;
448  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
449}
450
451// -------------------------------------------------------------------
452// VarintSize
453
454struct VarintSizeCase {
455  uint64 value;
456  int size;
457};
458
459inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
460  return os << c.value;
461}
462
463VarintSizeCase kVarintSizeCases[] = {
464  {0u, 1},
465  {1u, 1},
466  {127u, 1},
467  {128u, 2},
468  {758923u, 3},
469  {4000000000u, 5},
470  {ULL(41256202580718336), 8},
471  {ULL(11964378330978735131), 10},
472};
473
474TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
475  if (kVarintSizeCases_case.value > 0xffffffffu) {
476    // Skip 64-bit values.
477    return;
478  }
479
480  EXPECT_EQ(kVarintSizeCases_case.size,
481    CodedOutputStream::VarintSize32(
482      static_cast<uint32>(kVarintSizeCases_case.value)));
483}
484
485TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
486  EXPECT_EQ(kVarintSizeCases_case.size,
487    CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
488}
489
490// -------------------------------------------------------------------
491// Fixed-size int tests
492
493struct Fixed32Case {
494  uint8 bytes[sizeof(uint32)];          // Encoded bytes.
495  uint32 value;                         // Parsed value.
496};
497
498struct Fixed64Case {
499  uint8 bytes[sizeof(uint64)];          // Encoded bytes.
500  uint64 value;                         // Parsed value.
501};
502
503inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
504  return os << "0x" << hex << c.value << dec;
505}
506
507inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
508  return os << "0x" << hex << c.value << dec;
509}
510
511Fixed32Case kFixed32Cases[] = {
512  {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
513  {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
514};
515
516Fixed64Case kFixed64Cases[] = {
517  {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
518  {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
519};
520
521TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
522  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
523  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
524
525  {
526    CodedInputStream coded_input(&input);
527
528    uint32 value;
529    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
530    EXPECT_EQ(kFixed32Cases_case.value, value);
531  }
532
533  EXPECT_EQ(sizeof(uint32), input.ByteCount());
534}
535
536TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
537  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
538  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
539
540  {
541    CodedInputStream coded_input(&input);
542
543    uint64 value;
544    EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
545    EXPECT_EQ(kFixed64Cases_case.value, value);
546  }
547
548  EXPECT_EQ(sizeof(uint64), input.ByteCount());
549}
550
551TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
552  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
553
554  {
555    CodedOutputStream coded_output(&output);
556
557    coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
558    EXPECT_FALSE(coded_output.HadError());
559
560    EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
561  }
562
563  EXPECT_EQ(sizeof(uint32), output.ByteCount());
564  EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
565}
566
567TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
568  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
569
570  {
571    CodedOutputStream coded_output(&output);
572
573    coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
574    EXPECT_FALSE(coded_output.HadError());
575
576    EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
577  }
578
579  EXPECT_EQ(sizeof(uint64), output.ByteCount());
580  EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
581}
582
583// Tests using the static methods to read fixed-size values from raw arrays.
584
585TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
586  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
587
588  uint32 value;
589  const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
590      buffer_, &value);
591  EXPECT_EQ(kFixed32Cases_case.value, value);
592  EXPECT_TRUE(end == buffer_ + sizeof(value));
593}
594
595TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
596  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
597
598  uint64 value;
599  const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
600      buffer_, &value);
601  EXPECT_EQ(kFixed64Cases_case.value, value);
602  EXPECT_TRUE(end == buffer_ + sizeof(value));
603}
604
605// -------------------------------------------------------------------
606// Raw reads and writes
607
608const char kRawBytes[] = "Some bytes which will be written and read raw.";
609
610TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
611  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
612  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
613  char read_buffer[sizeof(kRawBytes)];
614
615  {
616    CodedInputStream coded_input(&input);
617
618    EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
619    EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
620  }
621
622  EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
623}
624
625TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
626  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
627
628  {
629    CodedOutputStream coded_output(&output);
630
631    coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
632    EXPECT_FALSE(coded_output.HadError());
633
634    EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
635  }
636
637  EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
638  EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
639}
640
641TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
642  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
643  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
644
645  {
646    CodedInputStream coded_input(&input);
647
648    string str;
649    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
650    EXPECT_EQ(kRawBytes, str);
651  }
652
653  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
654}
655
656// Check to make sure ReadString doesn't crash on impossibly large strings.
657TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
658  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
659
660  {
661    CodedInputStream coded_input(&input);
662
663    string str;
664    // Try to read a gigabyte.
665    EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
666  }
667}
668
669TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
670  // Same test as above, except directly use a buffer. This used to cause
671  // crashes while the above did not.
672  uint8 buffer[8];
673  CodedInputStream coded_input(buffer, 8);
674  string str;
675  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
676}
677
678TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
679  scoped_array<uint8> buffer(new uint8[8]);
680  CodedInputStream coded_input(buffer.get(), 8);
681  string str;
682  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
683}
684
685TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnTotalLimit, kBlockSizes) {
686  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
687  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
688
689  {
690    CodedInputStream coded_input(&input);
691    coded_input.SetTotalBytesLimit(sizeof(kRawBytes), sizeof(kRawBytes));
692    EXPECT_EQ(sizeof(kRawBytes), coded_input.BytesUntilTotalBytesLimit());
693
694    string str;
695    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
696    EXPECT_EQ(sizeof(kRawBytes) - strlen(kRawBytes),
697              coded_input.BytesUntilTotalBytesLimit());
698    EXPECT_EQ(kRawBytes, str);
699    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
700    EXPECT_GE(str.capacity(), strlen(kRawBytes));
701  }
702
703  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
704}
705
706TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnPushedLimit, kBlockSizes) {
707  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
708  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
709
710  {
711    CodedInputStream coded_input(&input);
712    coded_input.PushLimit(sizeof(buffer_));
713
714    string str;
715    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
716    EXPECT_EQ(kRawBytes, str);
717    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
718    EXPECT_GE(str.capacity(), strlen(kRawBytes));
719  }
720
721  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
722}
723
724TEST_F(CodedStreamTest, ReadStringNoReservationIfLimitsNotSet) {
725  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
726  // Buffer size in the input must be smaller than sizeof(kRawBytes),
727  // otherwise check against capacity will fail as ReadStringInline()
728  // will handle the reading and will reserve the memory as needed.
729  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
730
731  {
732    CodedInputStream coded_input(&input);
733
734    string str;
735    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
736    EXPECT_EQ(kRawBytes, str);
737    // Note: this check depends on string class implementation. It
738    // expects that string will allocate more than strlen(kRawBytes)
739    // if the content of kRawBytes is appended to string in small
740    // chunks.
741    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
742    EXPECT_GE(str.capacity(), strlen(kRawBytes));
743  }
744
745  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
746}
747
748TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsNegative) {
749  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
750  // Buffer size in the input must be smaller than sizeof(kRawBytes),
751  // otherwise check against capacity will fail as ReadStringInline()
752  // will handle the reading and will reserve the memory as needed.
753  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
754
755  {
756    CodedInputStream coded_input(&input);
757    coded_input.PushLimit(sizeof(buffer_));
758
759    string str;
760    EXPECT_FALSE(coded_input.ReadString(&str, -1));
761    // Note: this check depends on string class implementation. It
762    // expects that string will always allocate the same amount of
763    // memory for an empty string.
764    EXPECT_EQ(string().capacity(), str.capacity());
765  }
766}
767
768TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsLarge) {
769  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
770  // Buffer size in the input must be smaller than sizeof(kRawBytes),
771  // otherwise check against capacity will fail as ReadStringInline()
772  // will handle the reading and will reserve the memory as needed.
773  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
774
775  {
776    CodedInputStream coded_input(&input);
777    coded_input.PushLimit(sizeof(buffer_));
778
779    string str;
780    EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
781    EXPECT_GT(1 << 30, str.capacity());
782  }
783}
784
785TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheLimit) {
786  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
787  // Buffer size in the input must be smaller than sizeof(kRawBytes),
788  // otherwise check against capacity will fail as ReadStringInline()
789  // will handle the reading and will reserve the memory as needed.
790  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
791
792  {
793    CodedInputStream coded_input(&input);
794    coded_input.PushLimit(16);
795
796    string str;
797    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
798    // Note: this check depends on string class implementation. It
799    // expects that string will allocate less than strlen(kRawBytes)
800    // for an empty string.
801    EXPECT_GT(strlen(kRawBytes), str.capacity());
802  }
803}
804
805TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheTotalBytesLimit) {
806  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
807  // Buffer size in the input must be smaller than sizeof(kRawBytes),
808  // otherwise check against capacity will fail as ReadStringInline()
809  // will handle the reading and will reserve the memory as needed.
810  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
811
812  {
813    CodedInputStream coded_input(&input);
814    coded_input.SetTotalBytesLimit(16, 16);
815
816    string str;
817    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
818    // Note: this check depends on string class implementation. It
819    // expects that string will allocate less than strlen(kRawBytes)
820    // for an empty string.
821    EXPECT_GT(strlen(kRawBytes), str.capacity());
822  }
823}
824
825TEST_F(CodedStreamTest,
826       ReadStringNoReservationSizeIsOverTheClosestLimit_GlobalLimitIsCloser) {
827  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
828  // Buffer size in the input must be smaller than sizeof(kRawBytes),
829  // otherwise check against capacity will fail as ReadStringInline()
830  // will handle the reading and will reserve the memory as needed.
831  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
832
833  {
834    CodedInputStream coded_input(&input);
835    coded_input.PushLimit(sizeof(buffer_));
836    coded_input.SetTotalBytesLimit(16, 16);
837
838    string str;
839    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
840    // Note: this check depends on string class implementation. It
841    // expects that string will allocate less than strlen(kRawBytes)
842    // for an empty string.
843    EXPECT_GT(strlen(kRawBytes), str.capacity());
844  }
845}
846
847TEST_F(CodedStreamTest,
848       ReadStringNoReservationSizeIsOverTheClosestLimit_LocalLimitIsCloser) {
849  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
850  // Buffer size in the input must be smaller than sizeof(kRawBytes),
851  // otherwise check against capacity will fail as ReadStringInline()
852  // will handle the reading and will reserve the memory as needed.
853  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
854
855  {
856    CodedInputStream coded_input(&input);
857    coded_input.PushLimit(16);
858    coded_input.SetTotalBytesLimit(sizeof(buffer_), sizeof(buffer_));
859    EXPECT_EQ(sizeof(buffer_), coded_input.BytesUntilTotalBytesLimit());
860
861    string str;
862    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
863    // Note: this check depends on string class implementation. It
864    // expects that string will allocate less than strlen(kRawBytes)
865    // for an empty string.
866    EXPECT_GT(strlen(kRawBytes), str.capacity());
867  }
868}
869
870
871// -------------------------------------------------------------------
872// Skip
873
874const char kSkipTestBytes[] =
875  "<Before skipping><To be skipped><After skipping>";
876
877TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
878  memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
879  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
880
881  {
882    CodedInputStream coded_input(&input);
883
884    string str;
885    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
886    EXPECT_EQ("<Before skipping>", str);
887    EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
888    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
889    EXPECT_EQ("<After skipping>", str);
890  }
891
892  EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
893}
894
895// -------------------------------------------------------------------
896// GetDirectBufferPointer
897
898TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
899  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
900  CodedInputStream coded_input(&input);
901
902  const void* ptr;
903  int size;
904
905  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
906  EXPECT_EQ(buffer_, ptr);
907  EXPECT_EQ(8, size);
908
909  // Peeking again should return the same pointer.
910  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
911  EXPECT_EQ(buffer_, ptr);
912  EXPECT_EQ(8, size);
913
914  // Skip forward in the same buffer then peek again.
915  EXPECT_TRUE(coded_input.Skip(3));
916  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
917  EXPECT_EQ(buffer_ + 3, ptr);
918  EXPECT_EQ(5, size);
919
920  // Skip to end of buffer and peek -- should get next buffer.
921  EXPECT_TRUE(coded_input.Skip(5));
922  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
923  EXPECT_EQ(buffer_ + 8, ptr);
924  EXPECT_EQ(8, size);
925}
926
927TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
928  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
929  CodedInputStream coded_input(&input);
930
931  const void* ptr;
932  int size;
933
934  coded_input.GetDirectBufferPointerInline(&ptr, &size);
935  EXPECT_EQ(buffer_, ptr);
936  EXPECT_EQ(8, size);
937
938  // Peeking again should return the same pointer.
939  coded_input.GetDirectBufferPointerInline(&ptr, &size);
940  EXPECT_EQ(buffer_, ptr);
941  EXPECT_EQ(8, size);
942
943  // Skip forward in the same buffer then peek again.
944  EXPECT_TRUE(coded_input.Skip(3));
945  coded_input.GetDirectBufferPointerInline(&ptr, &size);
946  EXPECT_EQ(buffer_ + 3, ptr);
947  EXPECT_EQ(5, size);
948
949  // Skip to end of buffer and peek -- should return false and provide an empty
950  // buffer. It does not try to Refresh().
951  EXPECT_TRUE(coded_input.Skip(5));
952  coded_input.GetDirectBufferPointerInline(&ptr, &size);
953  EXPECT_EQ(buffer_ + 8, ptr);
954  EXPECT_EQ(0, size);
955}
956
957TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
958  ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
959  CodedOutputStream coded_output(&output);
960
961  void* ptr;
962  int size;
963
964  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
965  EXPECT_EQ(buffer_, ptr);
966  EXPECT_EQ(8, size);
967
968  // Peeking again should return the same pointer.
969  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
970  EXPECT_EQ(buffer_, ptr);
971  EXPECT_EQ(8, size);
972
973  // Skip forward in the same buffer then peek again.
974  EXPECT_TRUE(coded_output.Skip(3));
975  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
976  EXPECT_EQ(buffer_ + 3, ptr);
977  EXPECT_EQ(5, size);
978
979  // Skip to end of buffer and peek -- should get next buffer.
980  EXPECT_TRUE(coded_output.Skip(5));
981  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
982  EXPECT_EQ(buffer_ + 8, ptr);
983  EXPECT_EQ(8, size);
984
985  // Skip over multiple buffers.
986  EXPECT_TRUE(coded_output.Skip(22));
987  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
988  EXPECT_EQ(buffer_ + 30, ptr);
989  EXPECT_EQ(2, size);
990}
991
992// -------------------------------------------------------------------
993// Limits
994
995TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
996  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
997
998  {
999    CodedInputStream coded_input(&input);
1000
1001    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1002    CodedInputStream::Limit limit = coded_input.PushLimit(8);
1003
1004    // Read until we hit the limit.
1005    uint32 value;
1006    EXPECT_EQ(8, coded_input.BytesUntilLimit());
1007    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1008    EXPECT_EQ(4, coded_input.BytesUntilLimit());
1009    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1010    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1011    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
1012    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1013
1014    coded_input.PopLimit(limit);
1015
1016    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1017    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1018  }
1019
1020  EXPECT_EQ(12, input.ByteCount());
1021}
1022
1023// Test what happens when we push two limits where the second (top) one is
1024// shorter.
1025TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
1026  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
1027
1028  {
1029    CodedInputStream coded_input(&input);
1030
1031    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1032    CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
1033    EXPECT_EQ(8, coded_input.BytesUntilLimit());
1034    CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
1035
1036    uint32 value;
1037
1038    // Read until we hit limit2, the top and shortest limit.
1039    EXPECT_EQ(4, coded_input.BytesUntilLimit());
1040    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1041    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1042    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
1043    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1044
1045    coded_input.PopLimit(limit2);
1046
1047    // Read until we hit limit1.
1048    EXPECT_EQ(4, coded_input.BytesUntilLimit());
1049    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1050    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1051    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
1052    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1053
1054    coded_input.PopLimit(limit1);
1055
1056    // No more limits.
1057    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1058    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1059  }
1060
1061  EXPECT_EQ(12, input.ByteCount());
1062}
1063
1064// Test what happens when we push two limits where the second (top) one is
1065// longer.  In this case, the top limit is shortened to match the previous
1066// limit.
1067TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
1068  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
1069
1070  {
1071    CodedInputStream coded_input(&input);
1072
1073    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1074    CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
1075    EXPECT_EQ(4, coded_input.BytesUntilLimit());
1076    CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
1077
1078    uint32 value;
1079
1080    // Read until we hit limit2.  Except, wait!  limit1 is shorter, so
1081    // we end up hitting that first, despite having 4 bytes to go on
1082    // limit2.
1083    EXPECT_EQ(4, coded_input.BytesUntilLimit());
1084    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1085    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1086    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
1087    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1088
1089    coded_input.PopLimit(limit2);
1090
1091    // OK, popped limit2, now limit1 is on top, which we've already hit.
1092    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1093    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
1094    EXPECT_EQ(0, coded_input.BytesUntilLimit());
1095
1096    coded_input.PopLimit(limit1);
1097
1098    // No more limits.
1099    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1100    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1101  }
1102
1103  EXPECT_EQ(8, input.ByteCount());
1104}
1105
1106TEST_F(CodedStreamTest, ExpectAtEnd) {
1107  // Test ExpectAtEnd(), which is based on limits.
1108  ArrayInputStream input(buffer_, sizeof(buffer_));
1109  CodedInputStream coded_input(&input);
1110
1111  EXPECT_FALSE(coded_input.ExpectAtEnd());
1112
1113  CodedInputStream::Limit limit = coded_input.PushLimit(4);
1114
1115  uint32 value;
1116  EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
1117  EXPECT_TRUE(coded_input.ExpectAtEnd());
1118
1119  coded_input.PopLimit(limit);
1120  EXPECT_FALSE(coded_input.ExpectAtEnd());
1121}
1122
1123TEST_F(CodedStreamTest, NegativeLimit) {
1124  // Check what happens when we push a negative limit.
1125  ArrayInputStream input(buffer_, sizeof(buffer_));
1126  CodedInputStream coded_input(&input);
1127
1128  CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
1129  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
1130  // "the limit is INT_MAX relative to the beginning of the stream".
1131  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1132  coded_input.PopLimit(limit);
1133}
1134
1135TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
1136  // Check what happens when we push a negative limit.
1137  ArrayInputStream input(buffer_, sizeof(buffer_));
1138  CodedInputStream coded_input(&input);
1139  ASSERT_TRUE(coded_input.Skip(128));
1140
1141  CodedInputStream::Limit limit = coded_input.PushLimit(-64);
1142  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
1143  // "the limit is INT_MAX relative to the beginning of the stream".
1144  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1145  coded_input.PopLimit(limit);
1146}
1147
1148TEST_F(CodedStreamTest, OverflowLimit) {
1149  // Check what happens when we push a limit large enough that its absolute
1150  // position is more than 2GB into the stream.
1151  ArrayInputStream input(buffer_, sizeof(buffer_));
1152  CodedInputStream coded_input(&input);
1153  ASSERT_TRUE(coded_input.Skip(128));
1154
1155  CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
1156  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
1157  // "the limit is INT_MAX relative to the beginning of the stream".
1158  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
1159  coded_input.PopLimit(limit);
1160}
1161
1162TEST_F(CodedStreamTest, TotalBytesLimit) {
1163  ArrayInputStream input(buffer_, sizeof(buffer_));
1164  CodedInputStream coded_input(&input);
1165  coded_input.SetTotalBytesLimit(16, -1);
1166  EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
1167
1168  string str;
1169  EXPECT_TRUE(coded_input.ReadString(&str, 16));
1170  EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
1171
1172  vector<string> errors;
1173
1174  {
1175    ScopedMemoryLog error_log;
1176    EXPECT_FALSE(coded_input.ReadString(&str, 1));
1177    errors = error_log.GetMessages(ERROR);
1178  }
1179
1180  ASSERT_EQ(1, errors.size());
1181  EXPECT_PRED_FORMAT2(testing::IsSubstring,
1182    "A protocol message was rejected because it was too big", errors[0]);
1183
1184  coded_input.SetTotalBytesLimit(32, -1);
1185  EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
1186  EXPECT_TRUE(coded_input.ReadString(&str, 16));
1187  EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
1188}
1189
1190TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
1191  // total_bytes_limit_ is not a valid place for a message to end.
1192
1193  ArrayInputStream input(buffer_, sizeof(buffer_));
1194  CodedInputStream coded_input(&input);
1195
1196  // Set both total_bytes_limit and a regular limit at 16 bytes.
1197  coded_input.SetTotalBytesLimit(16, -1);
1198  CodedInputStream::Limit limit = coded_input.PushLimit(16);
1199
1200  // Read 16 bytes.
1201  string str;
1202  EXPECT_TRUE(coded_input.ReadString(&str, 16));
1203
1204  // Read a tag.  Should fail, but report being a valid endpoint since it's
1205  // a regular limit.
1206  EXPECT_EQ(0, coded_input.ReadTag());
1207  EXPECT_TRUE(coded_input.ConsumedEntireMessage());
1208
1209  // Pop the limit.
1210  coded_input.PopLimit(limit);
1211
1212  // Read a tag.  Should fail, and report *not* being a valid endpoint, since
1213  // this time we're hitting the total bytes limit.
1214  EXPECT_EQ(0, coded_input.ReadTag());
1215  EXPECT_FALSE(coded_input.ConsumedEntireMessage());
1216}
1217
1218// This method is used by the tests below.
1219// It constructs a CodedInputStream with the given limits and tries to read 2KiB
1220// of data from it. Then it returns the logged errors and warnings in the given
1221// vectors.
1222void CodedStreamTest::SetupTotalBytesLimitWarningTest(
1223    int total_bytes_limit, int warning_threshold,
1224    vector<string>* out_errors, vector<string>* out_warnings) {
1225  ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128);
1226
1227  ScopedMemoryLog scoped_log;
1228  {
1229    CodedInputStream input(&raw_input);
1230    input.SetTotalBytesLimit(total_bytes_limit, warning_threshold);
1231    string str;
1232    EXPECT_TRUE(input.ReadString(&str, 2048));
1233  }
1234
1235  *out_errors = scoped_log.GetMessages(ERROR);
1236  *out_warnings = scoped_log.GetMessages(WARNING);
1237}
1238
1239TEST_F(CodedStreamTest, TotalBytesLimitWarning) {
1240  vector<string> errors;
1241  vector<string> warnings;
1242  SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
1243
1244  EXPECT_EQ(0, errors.size());
1245
1246  ASSERT_EQ(2, warnings.size());
1247  EXPECT_PRED_FORMAT2(testing::IsSubstring,
1248    "Reading dangerously large protocol message.  If the message turns out to "
1249    "be larger than 10240 bytes, parsing will be halted for security reasons.",
1250    warnings[0]);
1251  EXPECT_PRED_FORMAT2(testing::IsSubstring,
1252    "The total number of bytes read was 2048",
1253    warnings[1]);
1254}
1255
1256TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
1257  vector<string> errors;
1258  vector<string> warnings;
1259
1260  // Test with -1
1261  SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
1262  EXPECT_EQ(0, errors.size());
1263  EXPECT_EQ(0, warnings.size());
1264
1265  // Test again with -2, expecting the same result
1266  SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
1267  EXPECT_EQ(0, errors.size());
1268  EXPECT_EQ(0, warnings.size());
1269}
1270
1271
1272TEST_F(CodedStreamTest, RecursionLimit) {
1273  ArrayInputStream input(buffer_, sizeof(buffer_));
1274  CodedInputStream coded_input(&input);
1275  coded_input.SetRecursionLimit(4);
1276
1277  // This is way too much testing for a counter.
1278  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
1279  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
1280  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
1281  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
1282  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
1283  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
1284  coded_input.DecrementRecursionDepth();                   // 5
1285  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
1286  coded_input.DecrementRecursionDepth();                   // 5
1287  coded_input.DecrementRecursionDepth();                   // 4
1288  coded_input.DecrementRecursionDepth();                   // 3
1289  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
1290  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
1291  coded_input.DecrementRecursionDepth();                   // 4
1292  coded_input.DecrementRecursionDepth();                   // 3
1293  coded_input.DecrementRecursionDepth();                   // 2
1294  coded_input.DecrementRecursionDepth();                   // 1
1295  coded_input.DecrementRecursionDepth();                   // 0
1296  coded_input.DecrementRecursionDepth();                   // 0
1297  coded_input.DecrementRecursionDepth();                   // 0
1298  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
1299  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
1300  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
1301  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
1302  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
1303
1304  coded_input.SetRecursionLimit(6);
1305  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 6
1306  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 7
1307}
1308
1309
1310class ReallyBigInputStream : public ZeroCopyInputStream {
1311 public:
1312  ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
1313  ~ReallyBigInputStream() {}
1314
1315  // implements ZeroCopyInputStream ----------------------------------
1316  bool Next(const void** data, int* size) {
1317    // We only expect BackUp() to be called at the end.
1318    EXPECT_EQ(0, backup_amount_);
1319
1320    switch (buffer_count_++) {
1321      case 0:
1322        *data = buffer_;
1323        *size = sizeof(buffer_);
1324        return true;
1325      case 1:
1326        // Return an enormously large buffer that, when combined with the 1k
1327        // returned already, should overflow the total_bytes_read_ counter in
1328        // CodedInputStream.  Note that we'll only read the first 1024 bytes
1329        // of this buffer so it's OK that we have it point at buffer_.
1330        *data = buffer_;
1331        *size = INT_MAX;
1332        return true;
1333      default:
1334        return false;
1335    }
1336  }
1337
1338  void BackUp(int count) {
1339    backup_amount_ = count;
1340  }
1341
1342  bool Skip(int count)    { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
1343  int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
1344
1345  int backup_amount_;
1346
1347 private:
1348  char buffer_[1024];
1349  int64 buffer_count_;
1350};
1351
1352TEST_F(CodedStreamTest, InputOver2G) {
1353  // CodedInputStream should gracefully handle input over 2G and call
1354  // input.BackUp() with the correct number of bytes on destruction.
1355  ReallyBigInputStream input;
1356
1357  vector<string> errors;
1358
1359  {
1360    ScopedMemoryLog error_log;
1361    CodedInputStream coded_input(&input);
1362    string str;
1363    EXPECT_TRUE(coded_input.ReadString(&str, 512));
1364    EXPECT_TRUE(coded_input.ReadString(&str, 1024));
1365    errors = error_log.GetMessages(ERROR);
1366  }
1367
1368  EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
1369  EXPECT_EQ(0, errors.size());
1370}
1371
1372// ===================================================================
1373
1374
1375}  // namespace
1376}  // namespace io
1377}  // namespace protobuf
1378}  // namespace google
1379