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