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