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