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