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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:56