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