1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
35 // This file contains tests and benchmarks.
39 #include <google/protobuf/io/coded_stream.h>
43 #include <google/protobuf/stubs/common.h>
44 #include <google/protobuf/testing/googletest.h>
45 #include <gtest/gtest.h>
46 #include <google/protobuf/io/zero_copy_stream_impl.h>
49 // This declares an unsigned long long integer literal in a portable way.
50 // (The original macro is way too big and ruins my formatting.)
52 #define ULL(x) GOOGLE_ULONGLONG(x)
59 // ===================================================================
60 // Data-Driven Test Infrastructure
62 // TEST_1D and TEST_2D are macros I'd eventually like to see added to
63 // gTest. These macros can be used to declare tests which should be
64 // run multiple times, once for each item in some input array. TEST_1D
65 // tests all cases in a single input array. TEST_2D tests all
66 // combinations of cases from two arrays. The arrays must be statically
67 // defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
69 // int kCases[] = {1, 2, 3, 4}
70 // TEST_1D(MyFixture, MyTest, kCases) {
71 // EXPECT_GT(kCases_case, 0);
74 // This test iterates through the numbers 1, 2, 3, and 4 and tests that
75 // they are all grater than zero. In case of failure, the exact case
76 // which failed will be printed. The case type must be printable using
77 // ostream::operator<<.
79 // TODO(kenton): gTest now supports "parameterized tests" which would be
80 // a better way to accomplish this. Rewrite when time permits.
82 #define TEST_1D(FIXTURE, NAME, CASES) \
83 class FIXTURE##_##NAME##_DD : public FIXTURE { \
85 template <typename CaseType> \
86 void DoSingleCase(const CaseType& CASES##_case); \
89 TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
90 for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
91 SCOPED_TRACE(testing::Message() \
92 << #CASES " case #" << i << ": " << CASES[i]); \
93 DoSingleCase(CASES[i]); \
97 template <typename CaseType> \
98 void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
100 #define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
101 class FIXTURE##_##NAME##_DD : public FIXTURE { \
103 template <typename CaseType1, typename CaseType2> \
104 void DoSingleCase(const CaseType1& CASES1##_case, \
105 const CaseType2& CASES2##_case); \
108 TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
109 for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
110 for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
111 SCOPED_TRACE(testing::Message() \
112 << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
113 << #CASES2 " case #" << j << ": " << CASES2[j]); \
114 DoSingleCase(CASES1[i], CASES2[j]); \
119 template <typename CaseType1, typename CaseType2> \
120 void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
121 const CaseType2& CASES2##_case)
123 // ===================================================================
125 class CodedStreamTest : public testing::Test {
127 // Helper method used by tests for bytes warning. See implementation comment
128 // for further information.
129 static void SetupTotalBytesLimitWarningTest(
130 int total_bytes_limit, int warning_threshold,
131 vector<string>* out_errors, vector<string>* out_warnings);
133 // Buffer used during most of the tests. This assumes tests run sequentially.
134 static const int kBufferSize = 1024 * 64;
135 static uint8 buffer_[kBufferSize];
138 uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
140 // We test each operation over a variety of block sizes to insure that
141 // we test cases where reads or writes cross buffer boundaries, cases
142 // where they don't, and cases where there is so much buffer left that
143 // we can use special optimized paths that don't worry about bounds
145 const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
147 // -------------------------------------------------------------------
151 uint8 bytes[10]; // Encoded bytes.
152 int size; // Encoded size, in bytes.
153 uint64 value; // Parsed value.
156 inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
157 return os << c.value;
160 VarintCase kVarintCases[] = {
165 {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882
166 {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5, // 2961488830
167 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
171 {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5, // 7256456126
172 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
174 {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8, // 41256202580718336
175 (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
176 (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
178 // 11964378330978735131
179 {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
180 (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
181 (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
182 (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
185 TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
186 memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
187 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
190 CodedInputStream coded_input(&input);
193 EXPECT_TRUE(coded_input.ReadVarint32(&value));
194 EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
197 EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
200 TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
201 memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
202 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
205 CodedInputStream coded_input(&input);
207 uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
208 EXPECT_EQ(expected_value, coded_input.ReadTag());
210 EXPECT_TRUE(coded_input.LastTagWas(expected_value));
211 EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
214 EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
217 // This is the regression test that verifies that there is no issues
218 // with the empty input buffers handling.
219 TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
220 class In : public ZeroCopyInputStream {
224 virtual bool Next(const void** data, int* size) {
229 virtual void BackUp(int count) {
230 GOOGLE_LOG(FATAL) << "Tests never call this.";
232 virtual bool Skip(int count) {
233 GOOGLE_LOG(FATAL) << "Tests never call this.";
236 virtual int64 ByteCount() const { return 0; }
239 CodedInputStream input(&in);
241 EXPECT_TRUE(input.ConsumedEntireMessage());
244 TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
245 // Leave one byte at the beginning of the buffer so we can read it
246 // to force the first buffer to be loaded.
248 memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
249 ArrayInputStream input(buffer_, sizeof(buffer_));
252 CodedInputStream coded_input(&input);
254 // Read one byte to force coded_input.Refill() to be called. Otherwise,
255 // ExpectTag() will return a false negative.
257 coded_input.ReadRaw(&dummy, 1);
258 EXPECT_EQ((uint)'\0', (uint)dummy);
260 uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
262 // ExpectTag() produces false negatives for large values.
263 if (kVarintCases_case.size <= 2) {
264 EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
265 EXPECT_TRUE(coded_input.ExpectTag(expected_value));
267 EXPECT_FALSE(coded_input.ExpectTag(expected_value));
271 if (kVarintCases_case.size <= 2) {
272 EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
274 EXPECT_EQ(1, input.ByteCount());
278 TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
279 memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
281 const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
283 // If the expectation succeeds, it should return a pointer past the tag.
284 if (kVarintCases_case.size <= 2) {
286 CodedInputStream::ExpectTagFromArray(buffer_,
287 expected_value + 1));
288 EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
289 CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
292 CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
296 TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
297 memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
298 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
301 CodedInputStream coded_input(&input);
304 EXPECT_TRUE(coded_input.ReadVarint64(&value));
305 EXPECT_EQ(kVarintCases_case.value, value);
308 EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
311 TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
312 if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
313 // Skip this test for the 64-bit values.
317 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
320 CodedOutputStream coded_output(&output);
322 coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
323 EXPECT_FALSE(coded_output.HadError());
325 EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
328 EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
330 memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
333 TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
334 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
337 CodedOutputStream coded_output(&output);
339 coded_output.WriteVarint64(kVarintCases_case.value);
340 EXPECT_FALSE(coded_output.HadError());
342 EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
345 EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
347 memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
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)
354 int32 kSignExtendedVarintCases[] = {
355 0, 1, -1, 1237894, -37895138
358 TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
359 kSignExtendedVarintCases, kBlockSizes) {
360 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
363 CodedOutputStream coded_output(&output);
365 coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
366 EXPECT_FALSE(coded_output.HadError());
368 if (kSignExtendedVarintCases_case < 0) {
369 EXPECT_EQ(10, coded_output.ByteCount());
371 EXPECT_LE(coded_output.ByteCount(), 5);
375 if (kSignExtendedVarintCases_case < 0) {
376 EXPECT_EQ(10, output.ByteCount());
378 EXPECT_LE(output.ByteCount(), 5);
381 // Read value back in as a varint64 and insure it matches.
382 ArrayInputStream input(buffer_, sizeof(buffer_));
385 CodedInputStream coded_input(&input);
388 EXPECT_TRUE(coded_input.ReadVarint64(&value));
390 EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
393 EXPECT_EQ(output.ByteCount(), input.ByteCount());
399 // -------------------------------------------------------------------
400 // Varint failure test.
402 struct VarintErrorCase {
408 inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
409 return os << "size " << c.size;
412 const VarintErrorCase kVarintErrorCases[] = {
413 // Control case. (Insures that there isn't something else wrong that
414 // makes parsing always fail.)
420 // Input ends unexpectedly.
421 {{0xf0, 0xab}, 2, false},
423 // Input ends unexpectedly after 32 bits.
424 {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
426 // Longer than 10 bytes.
427 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
431 TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
432 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
433 ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
435 CodedInputStream coded_input(&input);
438 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
441 TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
442 memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
443 ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
445 CodedInputStream coded_input(&input);
448 EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
451 // -------------------------------------------------------------------
454 struct VarintSizeCase {
459 inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
460 return os << c.value;
463 VarintSizeCase kVarintSizeCases[] = {
470 {ULL(41256202580718336), 8},
471 {ULL(11964378330978735131), 10},
474 TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
475 if (kVarintSizeCases_case.value > 0xffffffffu) {
476 // Skip 64-bit values.
480 EXPECT_EQ(kVarintSizeCases_case.size,
481 CodedOutputStream::VarintSize32(
482 static_cast<uint32>(kVarintSizeCases_case.value)));
485 TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
486 EXPECT_EQ(kVarintSizeCases_case.size,
487 CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
490 // -------------------------------------------------------------------
491 // Fixed-size int tests
494 uint8 bytes[sizeof(uint32)]; // Encoded bytes.
495 uint32 value; // Parsed value.
499 uint8 bytes[sizeof(uint64)]; // Encoded bytes.
500 uint64 value; // Parsed value.
503 inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
504 return os << "0x" << hex << c.value << dec;
507 inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
508 return os << "0x" << hex << c.value << dec;
511 Fixed32Case kFixed32Cases[] = {
512 {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
513 {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
516 Fixed64Case kFixed64Cases[] = {
517 {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
518 {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
521 TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
522 memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
523 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
526 CodedInputStream coded_input(&input);
529 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
530 EXPECT_EQ(kFixed32Cases_case.value, value);
533 EXPECT_EQ(sizeof(uint32), input.ByteCount());
536 TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
537 memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
538 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
541 CodedInputStream coded_input(&input);
544 EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
545 EXPECT_EQ(kFixed64Cases_case.value, value);
548 EXPECT_EQ(sizeof(uint64), input.ByteCount());
551 TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
552 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
555 CodedOutputStream coded_output(&output);
557 coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
558 EXPECT_FALSE(coded_output.HadError());
560 EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
563 EXPECT_EQ(sizeof(uint32), output.ByteCount());
564 EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
567 TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
568 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
571 CodedOutputStream coded_output(&output);
573 coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
574 EXPECT_FALSE(coded_output.HadError());
576 EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
579 EXPECT_EQ(sizeof(uint64), output.ByteCount());
580 EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
583 // Tests using the static methods to read fixed-size values from raw arrays.
585 TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
586 memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
589 const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
591 EXPECT_EQ(kFixed32Cases_case.value, value);
592 EXPECT_TRUE(end == buffer_ + sizeof(value));
595 TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
596 memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
599 const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
601 EXPECT_EQ(kFixed64Cases_case.value, value);
602 EXPECT_TRUE(end == buffer_ + sizeof(value));
605 // -------------------------------------------------------------------
606 // Raw reads and writes
608 const char kRawBytes[] = "Some bytes which will be written and read raw.";
610 TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
611 memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
612 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
613 char read_buffer[sizeof(kRawBytes)];
616 CodedInputStream coded_input(&input);
618 EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
619 EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
622 EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
625 TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
626 ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
629 CodedOutputStream coded_output(&output);
631 coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
632 EXPECT_FALSE(coded_output.HadError());
634 EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
637 EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
638 EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
641 TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
642 memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
643 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
646 CodedInputStream coded_input(&input);
649 EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
650 EXPECT_EQ(kRawBytes, str);
653 EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
656 // Check to make sure ReadString doesn't crash on impossibly large strings.
657 TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
658 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
661 CodedInputStream coded_input(&input);
664 // Try to read a gigabyte.
665 EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
669 TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
670 // Same test as above, except directly use a buffer. This used to cause
671 // crashes while the above did not.
673 CodedInputStream coded_input(buffer, 8);
675 EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
678 TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
679 scoped_array<uint8> buffer(new uint8[8]);
680 CodedInputStream coded_input(buffer.get(), 8);
682 EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
686 // -------------------------------------------------------------------
689 const char kSkipTestBytes[] =
690 "<Before skipping><To be skipped><After skipping>";
691 const char kSkipOutputTestBytes[] =
692 "-----------------<To be skipped>----------------";
694 TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
695 memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
696 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
699 CodedInputStream coded_input(&input);
702 EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
703 EXPECT_EQ("<Before skipping>", str);
704 EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
705 EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
706 EXPECT_EQ("<After skipping>", str);
709 EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
712 // -------------------------------------------------------------------
713 // GetDirectBufferPointer
715 TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
716 ArrayInputStream input(buffer_, sizeof(buffer_), 8);
717 CodedInputStream coded_input(&input);
722 EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
723 EXPECT_EQ(buffer_, ptr);
726 // Peeking again should return the same pointer.
727 EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
728 EXPECT_EQ(buffer_, ptr);
731 // Skip forward in the same buffer then peek again.
732 EXPECT_TRUE(coded_input.Skip(3));
733 EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
734 EXPECT_EQ(buffer_ + 3, ptr);
737 // Skip to end of buffer and peek -- should get next buffer.
738 EXPECT_TRUE(coded_input.Skip(5));
739 EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
740 EXPECT_EQ(buffer_ + 8, ptr);
744 TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
745 ArrayInputStream input(buffer_, sizeof(buffer_), 8);
746 CodedInputStream coded_input(&input);
751 coded_input.GetDirectBufferPointerInline(&ptr, &size);
752 EXPECT_EQ(buffer_, ptr);
755 // Peeking again should return the same pointer.
756 coded_input.GetDirectBufferPointerInline(&ptr, &size);
757 EXPECT_EQ(buffer_, ptr);
760 // Skip forward in the same buffer then peek again.
761 EXPECT_TRUE(coded_input.Skip(3));
762 coded_input.GetDirectBufferPointerInline(&ptr, &size);
763 EXPECT_EQ(buffer_ + 3, ptr);
766 // Skip to end of buffer and peek -- should return false and provide an empty
767 // buffer. It does not try to Refresh().
768 EXPECT_TRUE(coded_input.Skip(5));
769 coded_input.GetDirectBufferPointerInline(&ptr, &size);
770 EXPECT_EQ(buffer_ + 8, ptr);
774 TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
775 ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
776 CodedOutputStream coded_output(&output);
781 EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
782 EXPECT_EQ(buffer_, ptr);
785 // Peeking again should return the same pointer.
786 EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
787 EXPECT_EQ(buffer_, ptr);
790 // Skip forward in the same buffer then peek again.
791 EXPECT_TRUE(coded_output.Skip(3));
792 EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
793 EXPECT_EQ(buffer_ + 3, ptr);
796 // Skip to end of buffer and peek -- should get next buffer.
797 EXPECT_TRUE(coded_output.Skip(5));
798 EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
799 EXPECT_EQ(buffer_ + 8, ptr);
802 // Skip over multiple buffers.
803 EXPECT_TRUE(coded_output.Skip(22));
804 EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
805 EXPECT_EQ(buffer_ + 30, ptr);
809 // -------------------------------------------------------------------
812 TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
813 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
816 CodedInputStream coded_input(&input);
818 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
819 CodedInputStream::Limit limit = coded_input.PushLimit(8);
821 // Read until we hit the limit.
823 EXPECT_EQ(8, coded_input.BytesUntilLimit());
824 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
825 EXPECT_EQ(4, coded_input.BytesUntilLimit());
826 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
827 EXPECT_EQ(0, coded_input.BytesUntilLimit());
828 EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
829 EXPECT_EQ(0, coded_input.BytesUntilLimit());
831 coded_input.PopLimit(limit);
833 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
834 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
837 EXPECT_EQ(12, input.ByteCount());
840 // Test what happens when we push two limits where the second (top) one is
842 TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
843 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
846 CodedInputStream coded_input(&input);
848 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
849 CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
850 EXPECT_EQ(8, coded_input.BytesUntilLimit());
851 CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
855 // Read until we hit limit2, the top and shortest limit.
856 EXPECT_EQ(4, coded_input.BytesUntilLimit());
857 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
858 EXPECT_EQ(0, coded_input.BytesUntilLimit());
859 EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
860 EXPECT_EQ(0, coded_input.BytesUntilLimit());
862 coded_input.PopLimit(limit2);
864 // Read until we hit limit1.
865 EXPECT_EQ(4, coded_input.BytesUntilLimit());
866 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
867 EXPECT_EQ(0, coded_input.BytesUntilLimit());
868 EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
869 EXPECT_EQ(0, coded_input.BytesUntilLimit());
871 coded_input.PopLimit(limit1);
874 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
875 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
878 EXPECT_EQ(12, input.ByteCount());
881 // Test what happens when we push two limits where the second (top) one is
882 // longer. In this case, the top limit is shortened to match the previous
884 TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
885 ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
888 CodedInputStream coded_input(&input);
890 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
891 CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
892 EXPECT_EQ(4, coded_input.BytesUntilLimit());
893 CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
897 // Read until we hit limit2. Except, wait! limit1 is shorter, so
898 // we end up hitting that first, despite having 4 bytes to go on
900 EXPECT_EQ(4, coded_input.BytesUntilLimit());
901 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
902 EXPECT_EQ(0, coded_input.BytesUntilLimit());
903 EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
904 EXPECT_EQ(0, coded_input.BytesUntilLimit());
906 coded_input.PopLimit(limit2);
908 // OK, popped limit2, now limit1 is on top, which we've already hit.
909 EXPECT_EQ(0, coded_input.BytesUntilLimit());
910 EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
911 EXPECT_EQ(0, coded_input.BytesUntilLimit());
913 coded_input.PopLimit(limit1);
916 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
917 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
920 EXPECT_EQ(8, input.ByteCount());
923 TEST_F(CodedStreamTest, ExpectAtEnd) {
924 // Test ExpectAtEnd(), which is based on limits.
925 ArrayInputStream input(buffer_, sizeof(buffer_));
926 CodedInputStream coded_input(&input);
928 EXPECT_FALSE(coded_input.ExpectAtEnd());
930 CodedInputStream::Limit limit = coded_input.PushLimit(4);
933 EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
934 EXPECT_TRUE(coded_input.ExpectAtEnd());
936 coded_input.PopLimit(limit);
937 EXPECT_FALSE(coded_input.ExpectAtEnd());
940 TEST_F(CodedStreamTest, NegativeLimit) {
941 // Check what happens when we push a negative limit.
942 ArrayInputStream input(buffer_, sizeof(buffer_));
943 CodedInputStream coded_input(&input);
945 CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
946 // BytesUntilLimit() returns -1 to mean "no limit", which actually means
947 // "the limit is INT_MAX relative to the beginning of the stream".
948 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
949 coded_input.PopLimit(limit);
952 TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
953 // Check what happens when we push a negative limit.
954 ArrayInputStream input(buffer_, sizeof(buffer_));
955 CodedInputStream coded_input(&input);
956 ASSERT_TRUE(coded_input.Skip(128));
958 CodedInputStream::Limit limit = coded_input.PushLimit(-64);
959 // BytesUntilLimit() returns -1 to mean "no limit", which actually means
960 // "the limit is INT_MAX relative to the beginning of the stream".
961 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
962 coded_input.PopLimit(limit);
965 TEST_F(CodedStreamTest, OverflowLimit) {
966 // Check what happens when we push a limit large enough that its absolute
967 // position is more than 2GB into the stream.
968 ArrayInputStream input(buffer_, sizeof(buffer_));
969 CodedInputStream coded_input(&input);
970 ASSERT_TRUE(coded_input.Skip(128));
972 CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
973 // BytesUntilLimit() returns -1 to mean "no limit", which actually means
974 // "the limit is INT_MAX relative to the beginning of the stream".
975 EXPECT_EQ(-1, coded_input.BytesUntilLimit());
976 coded_input.PopLimit(limit);
979 TEST_F(CodedStreamTest, TotalBytesLimit) {
980 ArrayInputStream input(buffer_, sizeof(buffer_));
981 CodedInputStream coded_input(&input);
982 coded_input.SetTotalBytesLimit(16, -1);
985 EXPECT_TRUE(coded_input.ReadString(&str, 16));
987 vector<string> errors;
990 ScopedMemoryLog error_log;
991 EXPECT_FALSE(coded_input.ReadString(&str, 1));
992 errors = error_log.GetMessages(ERROR);
995 ASSERT_EQ(1, errors.size());
996 EXPECT_PRED_FORMAT2(testing::IsSubstring,
997 "A protocol message was rejected because it was too big", errors[0]);
999 coded_input.SetTotalBytesLimit(32, -1);
1000 EXPECT_TRUE(coded_input.ReadString(&str, 16));
1003 TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
1004 // total_bytes_limit_ is not a valid place for a message to end.
1006 ArrayInputStream input(buffer_, sizeof(buffer_));
1007 CodedInputStream coded_input(&input);
1009 // Set both total_bytes_limit and a regular limit at 16 bytes.
1010 coded_input.SetTotalBytesLimit(16, -1);
1011 CodedInputStream::Limit limit = coded_input.PushLimit(16);
1015 EXPECT_TRUE(coded_input.ReadString(&str, 16));
1017 // Read a tag. Should fail, but report being a valid endpoint since it's
1019 EXPECT_EQ(0, coded_input.ReadTag());
1020 EXPECT_TRUE(coded_input.ConsumedEntireMessage());
1023 coded_input.PopLimit(limit);
1025 // Read a tag. Should fail, and report *not* being a valid endpoint, since
1026 // this time we're hitting the total bytes limit.
1027 EXPECT_EQ(0, coded_input.ReadTag());
1028 EXPECT_FALSE(coded_input.ConsumedEntireMessage());
1031 // This method is used by the tests below.
1032 // It constructs a CodedInputStream with the given limits and tries to read 2KiB
1033 // of data from it. Then it returns the logged errors and warnings in the given
1035 void CodedStreamTest::SetupTotalBytesLimitWarningTest(
1036 int total_bytes_limit, int warning_threshold,
1037 vector<string>* out_errors, vector<string>* out_warnings) {
1038 ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128);
1040 ScopedMemoryLog scoped_log;
1042 CodedInputStream input(&raw_input);
1043 input.SetTotalBytesLimit(total_bytes_limit, warning_threshold);
1045 EXPECT_TRUE(input.ReadString(&str, 2048));
1048 *out_errors = scoped_log.GetMessages(ERROR);
1049 *out_warnings = scoped_log.GetMessages(WARNING);
1052 TEST_F(CodedStreamTest, TotalBytesLimitWarning) {
1053 vector<string> errors;
1054 vector<string> warnings;
1055 SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
1057 EXPECT_EQ(0, errors.size());
1059 ASSERT_EQ(2, warnings.size());
1060 EXPECT_PRED_FORMAT2(testing::IsSubstring,
1061 "Reading dangerously large protocol message. If the message turns out to "
1062 "be larger than 10240 bytes, parsing will be halted for security reasons.",
1064 EXPECT_PRED_FORMAT2(testing::IsSubstring,
1065 "The total number of bytes read was 2048",
1069 TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
1070 vector<string> errors;
1071 vector<string> warnings;
1074 SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
1075 EXPECT_EQ(0, errors.size());
1076 EXPECT_EQ(0, warnings.size());
1078 // Test again with -2, expecting the same result
1079 SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
1080 EXPECT_EQ(0, errors.size());
1081 EXPECT_EQ(0, warnings.size());
1085 TEST_F(CodedStreamTest, RecursionLimit) {
1086 ArrayInputStream input(buffer_, sizeof(buffer_));
1087 CodedInputStream coded_input(&input);
1088 coded_input.SetRecursionLimit(4);
1090 // This is way too much testing for a counter.
1091 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
1092 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
1093 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
1094 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
1095 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
1096 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
1097 coded_input.DecrementRecursionDepth(); // 5
1098 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
1099 coded_input.DecrementRecursionDepth(); // 5
1100 coded_input.DecrementRecursionDepth(); // 4
1101 coded_input.DecrementRecursionDepth(); // 3
1102 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
1103 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
1104 coded_input.DecrementRecursionDepth(); // 4
1105 coded_input.DecrementRecursionDepth(); // 3
1106 coded_input.DecrementRecursionDepth(); // 2
1107 coded_input.DecrementRecursionDepth(); // 1
1108 coded_input.DecrementRecursionDepth(); // 0
1109 coded_input.DecrementRecursionDepth(); // 0
1110 coded_input.DecrementRecursionDepth(); // 0
1111 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
1112 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
1113 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
1114 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
1115 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
1117 coded_input.SetRecursionLimit(6);
1118 EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6
1119 EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7
1123 class ReallyBigInputStream : public ZeroCopyInputStream {
1125 ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
1126 ~ReallyBigInputStream() {}
1128 // implements ZeroCopyInputStream ----------------------------------
1129 bool Next(const void** data, int* size) {
1130 // We only expect BackUp() to be called at the end.
1131 EXPECT_EQ(0, backup_amount_);
1133 switch (buffer_count_++) {
1136 *size = sizeof(buffer_);
1139 // Return an enormously large buffer that, when combined with the 1k
1140 // returned already, should overflow the total_bytes_read_ counter in
1141 // CodedInputStream. Note that we'll only read the first 1024 bytes
1142 // of this buffer so it's OK that we have it point at buffer_.
1151 void BackUp(int count) {
1152 backup_amount_ = count;
1155 bool Skip(int count) { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
1156 int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
1162 int64 buffer_count_;
1165 TEST_F(CodedStreamTest, InputOver2G) {
1166 // CodedInputStream should gracefully handle input over 2G and call
1167 // input.BackUp() with the correct number of bytes on destruction.
1168 ReallyBigInputStream input;
1170 vector<string> errors;
1173 ScopedMemoryLog error_log;
1174 CodedInputStream coded_input(&input);
1176 EXPECT_TRUE(coded_input.ReadString(&str, 512));
1177 EXPECT_TRUE(coded_input.ReadString(&str, 1024));
1178 errors = error_log.GetMessages(ERROR);
1181 EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
1182 EXPECT_EQ(0, errors.size());
1185 // ===================================================================
1190 } // namespace protobuf
1191 } // namespace google