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