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