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