1 // Copyright 2008 Google Inc. 2 // Author: Lincoln Smith 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #include <config.h> 17 #include "google/vcdecoder.h" 18 #include <stdlib.h> // free, posix_memalign 19 #include <string.h> // memcpy 20 #include <string> 21 #include "testing.h" 22 #include "varint_bigendian.h" 23 #include "vcdecoder_test.h" 24 #include "vcdiff_defs.h" // VCD_SOURCE 25 26 #ifdef HAVE_MALLOC_H 27 #include <malloc.h> 28 #endif // HAVE_MALLOC_H 29 30 #ifdef HAVE_SYS_MMAN_H 31 #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 32 #undef _XOPEN_SOURCE 33 #define _XOPEN_SOURCE 600 // posix_memalign 34 #endif 35 #include <sys/mman.h> // mprotect 36 #endif // HAVE_SYS_MMAN_H 37 38 #ifdef HAVE_UNISTD_H 39 #include <unistd.h> // getpagesize 40 #endif // HAVE_UNISTD_H 41 42 namespace open_vcdiff { 43 44 // Test headers, valid and invalid. 45 46 TEST_F(VCDiffInterleavedDecoderTest, DecodeHeaderOnly) { 47 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 48 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), 49 delta_file_header_.size(), 50 &output_)); 51 EXPECT_TRUE(decoder_.FinishDecoding()); 52 EXPECT_EQ("", output_); 53 } 54 55 TEST_F(VCDiffInterleavedDecoderTest, PartialHeaderNotEnough) { 56 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 57 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), 58 delta_file_header_.size() - 2, 59 &output_)); 60 EXPECT_FALSE(decoder_.FinishDecoding()); 61 EXPECT_EQ("", output_); 62 } 63 64 TEST_F(VCDiffInterleavedDecoderTest, BadMagicNumber) { 65 delta_file_[1] = 'Q' | 0x80; 66 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 67 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 68 delta_file_.size(), 69 &output_)); 70 EXPECT_EQ("", output_); 71 } 72 73 TEST_F(VCDiffInterleavedDecoderTest, BadVersionNumber) { 74 delta_file_[3] = 0x01; 75 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 76 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 77 delta_file_.size(), 78 &output_)); 79 EXPECT_EQ("", output_); 80 } 81 82 TEST_F(VCDiffInterleavedDecoderTest, SecondaryCompressionNotSupported) { 83 delta_file_[4] = 0x01; 84 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 85 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 86 delta_file_.size(), 87 &output_)); 88 EXPECT_EQ("", output_); 89 } 90 91 TEST_F(VCDiffInterleavedDecoderTest, Decode) { 92 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 93 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 94 delta_file_.size(), 95 &output_)); 96 EXPECT_TRUE(decoder_.FinishDecoding()); 97 EXPECT_EQ(expected_target_.c_str(), output_); 98 } 99 100 TEST_F(VCDiffInterleavedDecoderTest, DecodeWithChecksum) { 101 ComputeAndAddChecksum(); 102 InitializeDeltaFile(); 103 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 104 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 105 delta_file_.size(), 106 &output_)); 107 EXPECT_TRUE(decoder_.FinishDecoding()); 108 EXPECT_EQ(expected_target_.c_str(), output_); 109 } 110 111 TEST_F(VCDiffInterleavedDecoderTest, ChecksumDoesNotMatch) { 112 AddChecksum(0xBADBAD); 113 InitializeDeltaFile(); 114 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 115 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 116 delta_file_.size(), 117 &output_)); 118 EXPECT_EQ("", output_); 119 } 120 121 TEST_F(VCDiffInterleavedDecoderTest, ChecksumIsInvalid64BitVarint) { 122 static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 123 0x80, 0x80, 0x80, 0x00 }; 124 delta_window_header_[0] |= VCD_CHECKSUM; 125 delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint)); 126 // Adjust delta window size to include size of invalid Varint. 127 string size_of_invalid_varint; 128 VarintBE<int32_t>::AppendToString( 129 static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)), 130 &size_of_invalid_varint); 131 delta_window_header_.replace(4, 1, size_of_invalid_varint); 132 InitializeDeltaFile(); 133 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 134 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 135 delta_file_.size(), 136 &output_)); 137 EXPECT_EQ("", output_); 138 } 139 140 // Remove one byte from the length of the chunk to process, and 141 // verify that an error is returned for FinishDecoding(). 142 TEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindow) { 143 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 144 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 145 delta_file_.size() - 1, 146 &output_)); 147 EXPECT_FALSE(decoder_.FinishDecoding()); 148 // The decoder should not create more target bytes than were expected. 149 EXPECT_GE(expected_target_.size(), output_.size()); 150 } 151 152 TEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindowHeader) { 153 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 154 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 155 delta_file_header_.size() 156 + delta_window_header_.size() - 1, 157 &output_)); 158 EXPECT_FALSE(decoder_.FinishDecoding()); 159 // The decoder should not create more target bytes than were expected. 160 EXPECT_GE(expected_target_.size(), output_.size()); 161 } 162 163 TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesWindowSizeLimit) { 164 decoder_.SetMaximumTargetWindowSize(expected_target_.size()); 165 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 166 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 167 delta_file_.size(), 168 &output_)); 169 EXPECT_TRUE(decoder_.FinishDecoding()); 170 EXPECT_EQ(expected_target_.c_str(), output_); 171 } 172 173 TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesFileSizeLimit) { 174 decoder_.SetMaximumTargetFileSize(expected_target_.size()); 175 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 176 EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 177 delta_file_.size(), 178 &output_)); 179 EXPECT_TRUE(decoder_.FinishDecoding()); 180 EXPECT_EQ(expected_target_.c_str(), output_); 181 } 182 183 TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsWindowSizeLimit) { 184 decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1); 185 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 186 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 187 delta_file_.size(), 188 &output_)); 189 EXPECT_EQ("", output_); 190 } 191 192 TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsFileSizeLimit) { 193 decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1); 194 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 195 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 196 delta_file_.size(), 197 &output_)); 198 EXPECT_EQ("", output_); 199 } 200 201 // Fuzz bits to make sure decoder does not violently crash. 202 // This test has no expected behavior except that no crashes should occur. 203 // In some cases, changing bits will still decode to the correct target; 204 // for example, changing unused bits within a bitfield. 205 TEST_F(VCDiffInterleavedDecoderTest, FuzzBits) { 206 while (FuzzOneByteInDeltaFile()) { 207 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 208 if (decoder_.DecodeChunk(delta_file_.data(), 209 delta_file_.size(), 210 &output_)) { 211 decoder_.FinishDecoding(); 212 } 213 InitializeDeltaFile(); 214 output_.clear(); 215 } 216 } 217 218 // If a checksum is present, then fuzzing any of the bits may produce an error, 219 // but it should not result in an incorrect target being produced without 220 // an error. 221 TEST_F(VCDiffInterleavedDecoderTest, FuzzBitsWithChecksum) { 222 ComputeAndAddChecksum(); 223 InitializeDeltaFile(); 224 while (FuzzOneByteInDeltaFile()) { 225 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 226 if (decoder_.DecodeChunk(delta_file_.data(), 227 delta_file_.size(), 228 &output_)) { 229 if (decoder_.FinishDecoding()) { 230 // Decoding succeeded. Make sure the correct target was produced. 231 EXPECT_EQ(expected_target_.c_str(), output_); 232 } 233 } else { 234 EXPECT_EQ("", output_); 235 } 236 InitializeDeltaFile(); 237 output_.clear(); 238 } 239 } 240 241 TEST_F(VCDiffInterleavedDecoderTest, CopyMoreThanExpectedTarget) { 242 delta_file_[delta_file_header_.size() + 0x0C] = 243 FirstByteOfStringLength(kExpectedTarget); 244 delta_file_[delta_file_header_.size() + 0x0D] = 245 SecondByteOfStringLength(kExpectedTarget) + 1; 246 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 247 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 248 delta_file_.size(), 249 &output_)); 250 EXPECT_EQ("", output_); 251 } 252 253 TEST_F(VCDiffInterleavedDecoderTest, CopySizeZero) { 254 delta_file_[delta_file_header_.size() + 0x0C] = 0; 255 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 256 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 257 delta_file_.size(), 258 &output_)); 259 EXPECT_EQ("", output_); 260 } 261 262 TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooLargeByOne) { 263 ++delta_file_[delta_file_header_.size() + 0x0C]; 264 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 265 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 266 delta_file_.size(), 267 &output_)); 268 EXPECT_EQ("", output_); 269 } 270 271 TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooSmallByOne) { 272 --delta_file_[delta_file_header_.size() + 0x0C]; 273 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 274 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 275 delta_file_.size(), 276 &output_)); 277 EXPECT_EQ("", output_); 278 } 279 280 TEST_F(VCDiffInterleavedDecoderTest, CopySizeMaxInt) { 281 WriteMaxVarintAtOffset(0x0C, 1); 282 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 283 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 284 delta_file_.size(), 285 &output_)); 286 EXPECT_EQ("", output_); 287 } 288 289 TEST_F(VCDiffInterleavedDecoderTest, CopySizeNegative) { 290 WriteNegativeVarintAtOffset(0x0C, 1); 291 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 292 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 293 delta_file_.size(), 294 &output_)); 295 EXPECT_EQ("", output_); 296 } 297 298 TEST_F(VCDiffInterleavedDecoderTest, CopySizeInvalid) { 299 WriteInvalidVarintAtOffset(0x0C, 1); 300 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 301 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 302 delta_file_.size(), 303 &output_)); 304 EXPECT_EQ("", output_); 305 } 306 307 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressBeyondHereAddress) { 308 delta_file_[delta_file_header_.size() + 0x0D] = 309 FirstByteOfStringLength(kDictionary); 310 delta_file_[delta_file_header_.size() + 0x0E] = 311 SecondByteOfStringLength(kDictionary); 312 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 313 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 314 delta_file_.size(), 315 &output_)); 316 EXPECT_EQ("", output_); 317 } 318 319 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressMaxInt) { 320 WriteMaxVarintAtOffset(0x0D, 1); 321 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 322 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 323 delta_file_.size(), 324 &output_)); 325 EXPECT_EQ("", output_); 326 } 327 328 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressNegative) { 329 WriteNegativeVarintAtOffset(0x0D, 1); 330 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 331 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 332 delta_file_.size(), 333 &output_)); 334 EXPECT_EQ("", output_); 335 } 336 337 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressInvalid) { 338 WriteInvalidVarintAtOffset(0x0D, 1); 339 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 340 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 341 delta_file_.size(), 342 &output_)); 343 EXPECT_EQ("", output_); 344 } 345 346 TEST_F(VCDiffInterleavedDecoderTest, AddMoreThanExpectedTarget) { 347 delta_file_[delta_file_header_.size() + 0x0F] = 348 FirstByteOfStringLength(kExpectedTarget); 349 delta_file_[delta_file_header_.size() + 0x10] = 350 SecondByteOfStringLength(kExpectedTarget) + 1; 351 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 352 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 353 delta_file_.size(), 354 &output_)); 355 EXPECT_EQ("", output_); 356 } 357 358 TEST_F(VCDiffInterleavedDecoderTest, AddSizeZero) { 359 delta_file_[delta_file_header_.size() + 0x0F] = 0; 360 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 361 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 362 delta_file_.size(), 363 &output_)); 364 EXPECT_EQ("", output_); 365 } 366 367 TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooLargeByOne) { 368 ++delta_file_[delta_file_header_.size() + 0x0F]; 369 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 370 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 371 delta_file_.size(), 372 &output_)); 373 EXPECT_EQ("", output_); 374 } 375 376 TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooSmallByOne) { 377 --delta_file_[delta_file_header_.size() + 0x0F]; 378 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 379 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 380 delta_file_.size(), 381 &output_)); 382 EXPECT_EQ("", output_); 383 } 384 385 TEST_F(VCDiffInterleavedDecoderTest, AddSizeMaxInt) { 386 WriteMaxVarintAtOffset(0x0F, 1); 387 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 388 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 389 delta_file_.size(), 390 &output_)); 391 EXPECT_EQ("", output_); 392 } 393 394 TEST_F(VCDiffInterleavedDecoderTest, AddSizeNegative) { 395 WriteNegativeVarintAtOffset(0x0F, 1); 396 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 397 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 398 delta_file_.size(), 399 &output_)); 400 EXPECT_EQ("", output_); 401 } 402 403 TEST_F(VCDiffInterleavedDecoderTest, AddSizeInvalid) { 404 WriteInvalidVarintAtOffset(0x0F, 1); 405 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 406 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 407 delta_file_.size(), 408 &output_)); 409 EXPECT_EQ("", output_); 410 } 411 412 TEST_F(VCDiffInterleavedDecoderTest, RunMoreThanExpectedTarget) { 413 delta_file_[delta_file_header_.size() + 0x5F] = 414 FirstByteOfStringLength(kExpectedTarget); 415 delta_file_[delta_file_header_.size() + 0x60] = 416 SecondByteOfStringLength(kExpectedTarget) + 1; 417 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 418 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 419 delta_file_.size(), 420 &output_)); 421 EXPECT_EQ("", output_); 422 } 423 424 TEST_F(VCDiffInterleavedDecoderTest, RunSizeZero) { 425 delta_file_[delta_file_header_.size() + 0x5F] = 0; 426 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 427 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 428 delta_file_.size(), 429 &output_)); 430 EXPECT_EQ("", output_); 431 } 432 433 TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooLargeByOne) { 434 ++delta_file_[delta_file_header_.size() + 0x5F]; 435 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 436 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 437 delta_file_.size(), 438 &output_)); 439 EXPECT_EQ("", output_); 440 } 441 442 TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooSmallByOne) { 443 --delta_file_[delta_file_header_.size() + 0x5F]; 444 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 445 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 446 delta_file_.size(), 447 &output_)); 448 EXPECT_EQ("", output_); 449 } 450 451 TEST_F(VCDiffInterleavedDecoderTest, RunSizeMaxInt) { 452 WriteMaxVarintAtOffset(0x5F, 1); 453 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 454 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 455 delta_file_.size(), 456 &output_)); 457 EXPECT_EQ("", output_); 458 } 459 460 TEST_F(VCDiffInterleavedDecoderTest, RunSizeNegative) { 461 WriteNegativeVarintAtOffset(0x5F, 1); 462 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 463 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 464 delta_file_.size(), 465 &output_)); 466 EXPECT_EQ("", output_); 467 } 468 469 TEST_F(VCDiffInterleavedDecoderTest, RunSizeInvalid) { 470 WriteInvalidVarintAtOffset(0x5F, 1); 471 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 472 EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 473 delta_file_.size(), 474 &output_)); 475 EXPECT_EQ("", output_); 476 } 477 478 #if defined(HAVE_MPROTECT) && \ 479 (defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN)) 480 TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastEndOfBuffer) { 481 // Allocate two memory pages. 482 const int page_size = getpagesize(); 483 void* two_pages = NULL; 484 #ifdef HAVE_POSIX_MEMALIGN 485 posix_memalign(&two_pages, page_size, 2 * page_size); 486 #else // !HAVE_POSIX_MEMALIGN 487 two_pages = memalign(page_size, 2 * page_size); 488 #endif // HAVE_POSIX_MEMALIGN 489 char* const first_page = reinterpret_cast<char*>(two_pages); 490 char* const second_page = first_page + page_size; 491 492 // Place the delta string at the end of the first page. 493 char* delta_with_guard = second_page - delta_file_.size(); 494 memcpy(delta_with_guard, delta_file_.data(), delta_file_.size()); 495 496 // Make the second page unreadable. 497 mprotect(second_page, page_size, PROT_NONE); 498 499 // Now perform the decode operation, which will cause a segmentation fault 500 // if it reads past the end of the buffer. 501 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 502 EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard, 503 delta_file_.size(), 504 &output_)); 505 EXPECT_TRUE(decoder_.FinishDecoding()); 506 EXPECT_EQ(expected_target_.c_str(), output_); 507 508 // Undo the mprotect. 509 mprotect(second_page, page_size, PROT_READ|PROT_WRITE); 510 free(two_pages); 511 } 512 513 TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastBeginningOfBuffer) { 514 // Allocate two memory pages. 515 const int page_size = getpagesize(); 516 void* two_pages = NULL; 517 #ifdef HAVE_POSIX_MEMALIGN 518 posix_memalign(&two_pages, page_size, 2 * page_size); 519 #else // !HAVE_POSIX_MEMALIGN 520 two_pages = memalign(page_size, 2 * page_size); 521 #endif // HAVE_POSIX_MEMALIGN 522 char* const first_page = reinterpret_cast<char*>(two_pages); 523 char* const second_page = first_page + page_size; 524 525 // Make the first page unreadable. 526 mprotect(first_page, page_size, PROT_NONE); 527 528 // Place the delta string at the beginning of the second page. 529 char* delta_with_guard = second_page; 530 memcpy(delta_with_guard, delta_file_.data(), delta_file_.size()); 531 532 // Now perform the decode operation, which will cause a segmentation fault 533 // if it reads past the beginning of the buffer. 534 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 535 EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard, 536 delta_file_.size(), 537 &output_)); 538 EXPECT_TRUE(decoder_.FinishDecoding()); 539 EXPECT_EQ(expected_target_.c_str(), output_); 540 541 // Undo the mprotect. 542 mprotect(first_page, page_size, PROT_READ|PROT_WRITE); 543 free(two_pages); 544 } 545 #endif // HAVE_MPROTECT && (HAVE_MEMALIGN || HAVE_POSIX_MEMALIGN) 546 547 // These are the same tests as for VCDiffInterleavedDecoderTest, with the added 548 // complication that instead of calling DecodeChunk() once with the entire data 549 // set, DecodeChunk() is called once for each byte of input. This is intended 550 // to shake out any bugs with rewind and resume while parsing chunked data. 551 552 typedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte; 553 554 // Test headers, valid and invalid. 555 556 TEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeHeaderOnly) { 557 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 558 for (size_t i = 0; i < delta_file_header_.size(); ++i) { 559 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_header_[i], 1, &output_)); 560 } 561 EXPECT_TRUE(decoder_.FinishDecoding()); 562 EXPECT_EQ("", output_); 563 } 564 565 TEST_F(VCDiffInterleavedDecoderTestByteByByte, PartialHeaderNotEnough) { 566 delta_file_.resize(delta_file_header_.size() - 2); 567 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 568 for (size_t i = 0; i < delta_file_.size(); ++i) { 569 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 570 } 571 EXPECT_FALSE(decoder_.FinishDecoding()); 572 EXPECT_EQ("", output_); 573 } 574 575 TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadMagicNumber) { 576 delta_file_[1] = 'Q' | 0x80; 577 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 578 bool failed = false; 579 for (size_t i = 0; i < delta_file_.size(); ++i) { 580 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 581 // It should fail at the position that was altered 582 EXPECT_EQ(1U, i); 583 failed = true; 584 break; 585 } 586 } 587 EXPECT_TRUE(failed); 588 EXPECT_EQ("", output_); 589 } 590 591 TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadVersionNumber) { 592 delta_file_[3] = 0x01; 593 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 594 bool failed = false; 595 for (size_t i = 0; i < delta_file_.size(); ++i) { 596 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 597 failed = true; 598 // It should fail at the position that was altered 599 EXPECT_EQ(3U, i); 600 break; 601 } 602 } 603 EXPECT_TRUE(failed); 604 EXPECT_EQ("", output_); 605 } 606 607 TEST_F(VCDiffInterleavedDecoderTestByteByByte, 608 SecondaryCompressionNotSupported) { 609 delta_file_[4] = 0x01; 610 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 611 bool failed = false; 612 for (size_t i = 0; i < delta_file_.size(); ++i) { 613 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 614 failed = true; 615 // It should fail at the position that was altered 616 EXPECT_EQ(4U, i); 617 break; 618 } 619 } 620 EXPECT_TRUE(failed); 621 EXPECT_EQ("", output_); 622 } 623 624 TEST_F(VCDiffInterleavedDecoderTestByteByByte, Decode) { 625 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 626 for (size_t i = 0; i < delta_file_.size(); ++i) { 627 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 628 } 629 EXPECT_TRUE(decoder_.FinishDecoding()); 630 EXPECT_EQ(expected_target_.c_str(), output_); 631 } 632 633 TEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeWithChecksum) { 634 ComputeAndAddChecksum(); 635 InitializeDeltaFile(); 636 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 637 for (size_t i = 0; i < delta_file_.size(); ++i) { 638 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 639 } 640 EXPECT_TRUE(decoder_.FinishDecoding()); 641 EXPECT_EQ(expected_target_.c_str(), output_); 642 } 643 644 TEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumDoesNotMatch) { 645 AddChecksum(0xBADBAD); 646 InitializeDeltaFile(); 647 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 648 bool failed = false; 649 for (size_t i = 0; i < delta_file_.size(); ++i) { 650 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 651 failed = true; 652 // It should fail after decoding the entire delta file 653 EXPECT_EQ(delta_file_.size() - 1, i); 654 break; 655 } 656 } 657 EXPECT_TRUE(failed); 658 // The decoder should not create more target bytes than were expected. 659 EXPECT_GE(expected_target_.size(), output_.size()); 660 } 661 662 TEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumIsInvalid64BitVarint) { 663 static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 664 0x80, 0x80, 0x80, 0x00 }; 665 delta_window_header_[0] |= VCD_CHECKSUM; 666 delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint)); 667 // Adjust delta window size to include size of invalid Varint. 668 string size_of_invalid_varint; 669 VarintBE<int32_t>::AppendToString( 670 static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)), 671 &size_of_invalid_varint); 672 delta_window_header_.replace(4, 1, size_of_invalid_varint); 673 InitializeDeltaFile(); 674 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 675 bool failed = false; 676 for (size_t i = 0; i < delta_file_.size(); ++i) { 677 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 678 failed = true; 679 // It should fail while trying to interpret the checksum. 680 EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() - 2, i); 681 break; 682 } 683 } 684 EXPECT_TRUE(failed); 685 // The decoder should not create more target bytes than were expected. 686 EXPECT_GE(expected_target_.size(), output_.size()); 687 } 688 689 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesWindowSizeLimit) { 690 decoder_.SetMaximumTargetWindowSize(expected_target_.size()); 691 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 692 for (size_t i = 0; i < delta_file_.size(); ++i) { 693 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 694 } 695 EXPECT_TRUE(decoder_.FinishDecoding()); 696 EXPECT_EQ(expected_target_.c_str(), output_); 697 } 698 699 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesFileSizeLimit) { 700 decoder_.SetMaximumTargetFileSize(expected_target_.size()); 701 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 702 for (size_t i = 0; i < delta_file_.size(); ++i) { 703 EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 704 } 705 EXPECT_TRUE(decoder_.FinishDecoding()); 706 EXPECT_EQ(expected_target_.c_str(), output_); 707 } 708 709 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsWindowSizeLimit) { 710 decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1); 711 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 712 bool failed = false; 713 for (size_t i = 0; i < delta_file_.size(); ++i) { 714 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 715 failed = true; 716 break; 717 } 718 } 719 EXPECT_TRUE(failed); 720 EXPECT_EQ("", output_); 721 } 722 723 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsFileSizeLimit) { 724 decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1); 725 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 726 bool failed = false; 727 for (size_t i = 0; i < delta_file_.size(); ++i) { 728 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 729 failed = true; 730 break; 731 } 732 } 733 EXPECT_TRUE(failed); 734 EXPECT_EQ("", output_); 735 } 736 737 // Fuzz bits to make sure decoder does not violently crash. 738 // This test has no expected behavior except that no crashes should occur. 739 // In some cases, changing bits will still decode to the correct target; 740 // for example, changing unused bits within a bitfield. 741 TEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBits) { 742 while (FuzzOneByteInDeltaFile()) { 743 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 744 bool failed = false; 745 for (size_t i = 0; i < delta_file_.size(); ++i) { 746 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 747 failed = true; 748 break; 749 } 750 } 751 if (!failed) { 752 decoder_.FinishDecoding(); 753 } 754 InitializeDeltaFile(); 755 output_.clear(); 756 } 757 } 758 759 // If a checksum is present, then fuzzing any of the bits may produce an error, 760 // but it should not result in an incorrect target being produced without 761 // an error. 762 TEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBitsWithChecksum) { 763 ComputeAndAddChecksum(); 764 InitializeDeltaFile(); 765 while (FuzzOneByteInDeltaFile()) { 766 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 767 bool failed = false; 768 for (size_t i = 0; i < delta_file_.size(); ++i) { 769 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 770 failed = true; 771 break; 772 } 773 } 774 if (!failed) { 775 if (decoder_.FinishDecoding()) { 776 // Decoding succeeded. Make sure the correct target was produced. 777 EXPECT_EQ(expected_target_.c_str(), output_); 778 } 779 } 780 // The decoder should not create more target bytes than were expected. 781 EXPECT_GE(expected_target_.size(), output_.size()); 782 InitializeDeltaFile(); 783 output_.clear(); 784 } 785 } 786 787 TEST_F(VCDiffInterleavedDecoderTestByteByByte, 788 CopyInstructionsShouldFailIfNoSourceSegment) { 789 // Replace the Win_Indicator and the source size and source offset with a 790 // single 0 byte (a Win_Indicator for a window with no source segment.) 791 delta_window_header_.replace(0, 4, "\0", 1); 792 InitializeDeltaFile(); 793 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 794 bool failed = false; 795 for (size_t i = 0; i < delta_file_.size(); ++i) { 796 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 797 failed = true; 798 // The first COPY instruction should fail. 799 EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() + 2, i); 800 break; 801 } 802 } 803 EXPECT_TRUE(failed); 804 EXPECT_EQ("", output_); 805 } 806 807 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyMoreThanExpectedTarget) { 808 delta_file_[delta_file_header_.size() + 0x0C] = 809 FirstByteOfStringLength(kExpectedTarget); 810 delta_file_[delta_file_header_.size() + 0x0D] = 811 SecondByteOfStringLength(kExpectedTarget) + 1; 812 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 813 bool failed = false; 814 for (size_t i = 0; i < delta_file_.size(); ++i) { 815 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 816 failed = true; 817 // It should fail at the position that was altered 818 EXPECT_EQ(delta_file_header_.size() + 0x0D, i); 819 break; 820 } 821 } 822 EXPECT_TRUE(failed); 823 // The decoder should not create more target bytes than were expected. 824 EXPECT_GE(expected_target_.size(), output_.size()); 825 } 826 827 // A COPY instruction with an explicit size of 0 is not illegal according to the 828 // standard, although it is inefficient and should not be generated by any 829 // reasonable encoder. Changing the size of a COPY instruction to zero will 830 // cause a failure because the generated target window size will not match the 831 // expected target size. 832 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeZero) { 833 delta_file_[delta_file_header_.size() + 0x0C] = 0; 834 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 835 bool failed = false; 836 for (size_t i = 0; i < delta_file_.size(); ++i) { 837 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 838 failed = true; 839 break; 840 } 841 } 842 EXPECT_TRUE(failed); 843 // The decoder should not create more target bytes than were expected. 844 EXPECT_GE(expected_target_.size(), output_.size()); 845 } 846 847 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooLargeByOne) { 848 ++delta_file_[delta_file_header_.size() + 0x0C]; 849 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 850 bool failed = false; 851 for (size_t i = 0; i < delta_file_.size(); ++i) { 852 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 853 failed = true; 854 break; 855 } 856 } 857 EXPECT_TRUE(failed); 858 // The decoder should not create more target bytes than were expected. 859 EXPECT_GE(expected_target_.size(), output_.size()); 860 } 861 862 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooSmallByOne) { 863 --delta_file_[delta_file_header_.size() + 0x0C]; 864 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 865 bool failed = false; 866 for (size_t i = 0; i < delta_file_.size(); ++i) { 867 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 868 failed = true; 869 break; 870 } 871 } 872 EXPECT_TRUE(failed); 873 // The decoder should not create more target bytes than were expected. 874 EXPECT_GE(expected_target_.size(), output_.size()); 875 } 876 877 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeMaxInt) { 878 WriteMaxVarintAtOffset(0x0C, 1); 879 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 880 bool failed = false; 881 for (size_t i = 0; i < delta_file_.size(); ++i) { 882 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 883 failed = true; 884 // It should fail at the position that was altered 885 EXPECT_EQ(delta_file_header_.size() + 0x10, i); 886 break; 887 } 888 } 889 EXPECT_TRUE(failed); 890 // The decoder should not create more target bytes than were expected. 891 EXPECT_GE(expected_target_.size(), output_.size()); 892 } 893 894 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeNegative) { 895 WriteNegativeVarintAtOffset(0x0C, 1); 896 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 897 bool failed = false; 898 for (size_t i = 0; i < delta_file_.size(); ++i) { 899 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 900 failed = true; 901 // It should fail at the position that was altered 902 EXPECT_EQ(delta_file_header_.size() + 0x0F, i); 903 break; 904 } 905 } 906 EXPECT_TRUE(failed); 907 // The decoder should not create more target bytes than were expected. 908 EXPECT_GE(expected_target_.size(), output_.size()); 909 } 910 911 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeInvalid) { 912 WriteInvalidVarintAtOffset(0x0C, 1); 913 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 914 bool failed = false; 915 for (size_t i = 0; i < delta_file_.size(); ++i) { 916 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 917 failed = true; 918 // It should fail at the position that was altered 919 EXPECT_EQ(delta_file_header_.size() + 0x10, i); 920 break; 921 } 922 } 923 EXPECT_TRUE(failed); 924 // The decoder should not create more target bytes than were expected. 925 EXPECT_GE(expected_target_.size(), output_.size()); 926 } 927 928 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressBeyondHereAddress) { 929 delta_file_[delta_file_header_.size() + 0x0D] = 930 FirstByteOfStringLength(kDictionary); 931 delta_file_[delta_file_header_.size() + 0x0E] = 932 SecondByteOfStringLength(kDictionary); 933 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 934 bool failed = false; 935 for (size_t i = 0; i < delta_file_.size(); ++i) { 936 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 937 failed = true; 938 // It should fail at the position that was altered 939 EXPECT_EQ(delta_file_header_.size() + 0x0E, i); 940 break; 941 } 942 } 943 EXPECT_TRUE(failed); 944 // The decoder should not create more target bytes than were expected. 945 EXPECT_GE(expected_target_.size(), output_.size()); 946 } 947 948 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressMaxInt) { 949 WriteMaxVarintAtOffset(0x0D, 1); 950 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 951 bool failed = false; 952 for (size_t i = 0; i < delta_file_.size(); ++i) { 953 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 954 failed = true; 955 // It should fail at the position that was altered 956 EXPECT_EQ(delta_file_header_.size() + 0x11, i); 957 break; 958 } 959 } 960 EXPECT_TRUE(failed); 961 // The decoder should not create more target bytes than were expected. 962 EXPECT_GE(expected_target_.size(), output_.size()); 963 } 964 965 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressNegative) { 966 WriteNegativeVarintAtOffset(0x0D, 1); 967 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 968 bool failed = false; 969 for (size_t i = 0; i < delta_file_.size(); ++i) { 970 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 971 failed = true; 972 // It should fail at the position that was altered 973 EXPECT_EQ(delta_file_header_.size() + 0x10, i); 974 break; 975 } 976 } 977 EXPECT_TRUE(failed); 978 // The decoder should not create more target bytes than were expected. 979 EXPECT_GE(expected_target_.size(), output_.size()); 980 } 981 982 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressInvalid) { 983 WriteInvalidVarintAtOffset(0x0D, 1); 984 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 985 bool failed = false; 986 for (size_t i = 0; i < delta_file_.size(); ++i) { 987 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 988 failed = true; 989 // It should fail at the position that was altered 990 EXPECT_EQ(delta_file_header_.size() + 0x11, i); 991 break; 992 } 993 } 994 EXPECT_TRUE(failed); 995 // The decoder should not create more target bytes than were expected. 996 EXPECT_GE(expected_target_.size(), output_.size()); 997 } 998 999 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddMoreThanExpectedTarget) { 1000 delta_file_[delta_file_header_.size() + 0x0F] = 1001 FirstByteOfStringLength(kExpectedTarget); 1002 delta_file_[delta_file_header_.size() + 0x10] = 1003 SecondByteOfStringLength(kExpectedTarget) + 1; 1004 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1005 bool failed = false; 1006 for (size_t i = 0; i < delta_file_.size(); ++i) { 1007 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1008 failed = true; 1009 // It should fail at the position that was altered 1010 EXPECT_EQ(delta_file_header_.size() + 0x10, i); 1011 break; 1012 } 1013 } 1014 EXPECT_TRUE(failed); 1015 // The decoder should not create more target bytes than were expected. 1016 EXPECT_GE(expected_target_.size(), output_.size()); 1017 } 1018 1019 // An ADD instruction with an explicit size of 0 is not illegal according to the 1020 // standard, although it is inefficient and should not be generated by any 1021 // reasonable encoder. Changing the size of an ADD instruction to zero will 1022 // cause a failure because the generated target window size will not match the 1023 // expected target size. 1024 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeZero) { 1025 delta_file_[delta_file_header_.size() + 0x0F] = 0; 1026 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1027 bool failed = false; 1028 for (size_t i = 0; i < delta_file_.size(); ++i) { 1029 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1030 failed = true; 1031 break; 1032 } 1033 } 1034 EXPECT_TRUE(failed); 1035 // The decoder should not create more target bytes than were expected. 1036 EXPECT_GE(expected_target_.size(), output_.size()); 1037 } 1038 1039 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooLargeByOne) { 1040 ++delta_file_[delta_file_header_.size() + 0x0F]; 1041 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1042 bool failed = false; 1043 for (size_t i = 0; i < delta_file_.size(); ++i) { 1044 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1045 failed = true; 1046 break; 1047 } 1048 } 1049 EXPECT_TRUE(failed); 1050 // The decoder should not create more target bytes than were expected. 1051 EXPECT_GE(expected_target_.size(), output_.size()); 1052 } 1053 1054 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooSmallByOne) { 1055 --delta_file_[delta_file_header_.size() + 0x0F]; 1056 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1057 bool failed = false; 1058 for (size_t i = 0; i < delta_file_.size(); ++i) { 1059 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1060 failed = true; 1061 break; 1062 } 1063 } 1064 EXPECT_TRUE(failed); 1065 // The decoder should not create more target bytes than were expected. 1066 EXPECT_GE(expected_target_.size(), output_.size()); 1067 } 1068 1069 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeMaxInt) { 1070 WriteMaxVarintAtOffset(0x0F, 1); 1071 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1072 bool failed = false; 1073 for (size_t i = 0; i < delta_file_.size(); ++i) { 1074 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1075 failed = true; 1076 // It should fail at the position that was altered 1077 EXPECT_EQ(delta_file_header_.size() + 0x13, i); 1078 break; 1079 } 1080 } 1081 EXPECT_TRUE(failed); 1082 // The decoder should not create more target bytes than were expected. 1083 EXPECT_GE(expected_target_.size(), output_.size()); 1084 } 1085 1086 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeNegative) { 1087 WriteNegativeVarintAtOffset(0x0F, 1); 1088 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1089 bool failed = false; 1090 for (size_t i = 0; i < delta_file_.size(); ++i) { 1091 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1092 failed = true; 1093 // It should fail at the position that was altered 1094 EXPECT_EQ(delta_file_header_.size() + 0x12, i); 1095 break; 1096 } 1097 } 1098 EXPECT_TRUE(failed); 1099 // The decoder should not create more target bytes than were expected. 1100 EXPECT_GE(expected_target_.size(), output_.size()); 1101 } 1102 1103 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeInvalid) { 1104 WriteInvalidVarintAtOffset(0x0F, 1); 1105 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1106 bool failed = false; 1107 for (size_t i = 0; i < delta_file_.size(); ++i) { 1108 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1109 failed = true; 1110 // It should fail at the position that was altered 1111 EXPECT_EQ(delta_file_header_.size() + 0x13, i); 1112 break; 1113 } 1114 } 1115 EXPECT_TRUE(failed); 1116 // The decoder should not create more target bytes than were expected. 1117 EXPECT_GE(expected_target_.size(), output_.size()); 1118 } 1119 1120 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunMoreThanExpectedTarget) { 1121 delta_file_[delta_file_header_.size() + 0x5F] = 1122 FirstByteOfStringLength(kExpectedTarget); 1123 delta_file_[delta_file_header_.size() + 0x60] = 1124 SecondByteOfStringLength(kExpectedTarget) + 1; 1125 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1126 bool failed = false; 1127 for (size_t i = 0; i < delta_file_.size(); ++i) { 1128 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1129 failed = true; 1130 // It should fail at the position that was altered 1131 EXPECT_EQ(delta_file_header_.size() + 0x60, i); 1132 break; 1133 } 1134 } 1135 EXPECT_TRUE(failed); 1136 // The decoder should not create more target bytes than were expected. 1137 EXPECT_GE(expected_target_.size(), output_.size()); 1138 } 1139 1140 // A RUN instruction with an explicit size of 0 is not illegal according to the 1141 // standard, although it is inefficient and should not be generated by any 1142 // reasonable encoder. Changing the size of a RUN instruction to zero will 1143 // cause a failure because the generated target window size will not match the 1144 // expected target size. 1145 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeZero) { 1146 delta_file_[delta_file_header_.size() + 0x5F] = 0; 1147 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1148 bool failed = false; 1149 for (size_t i = 0; i < delta_file_.size(); ++i) { 1150 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1151 failed = true; 1152 break; 1153 } 1154 } 1155 EXPECT_TRUE(failed); 1156 // The decoder should not create more target bytes than were expected. 1157 EXPECT_GE(expected_target_.size(), output_.size()); 1158 } 1159 1160 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooLargeByOne) { 1161 ++delta_file_[delta_file_header_.size() + 0x5F]; 1162 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1163 bool failed = false; 1164 for (size_t i = 0; i < delta_file_.size(); ++i) { 1165 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1166 failed = true; 1167 break; 1168 } 1169 } 1170 EXPECT_TRUE(failed); 1171 // The decoder should not create more target bytes than were expected. 1172 EXPECT_GE(expected_target_.size(), output_.size()); 1173 } 1174 1175 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooSmallByOne) { 1176 --delta_file_[delta_file_header_.size() + 0x5F]; 1177 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1178 bool failed = false; 1179 for (size_t i = 0; i < delta_file_.size(); ++i) { 1180 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1181 failed = true; 1182 break; 1183 } 1184 } 1185 EXPECT_TRUE(failed); 1186 // The decoder should not create more target bytes than were expected. 1187 EXPECT_GE(expected_target_.size(), output_.size()); 1188 } 1189 1190 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeMaxInt) { 1191 WriteMaxVarintAtOffset(0x5F, 1); 1192 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1193 bool failed = false; 1194 for (size_t i = 0; i < delta_file_.size(); ++i) { 1195 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1196 failed = true; 1197 // It should fail at the position that was altered 1198 EXPECT_EQ(delta_file_header_.size() + 0x63, i); 1199 break; 1200 } 1201 } 1202 EXPECT_TRUE(failed); 1203 // The decoder should not create more target bytes than were expected. 1204 EXPECT_GE(expected_target_.size(), output_.size()); 1205 } 1206 1207 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeNegative) { 1208 WriteNegativeVarintAtOffset(0x5F, 1); 1209 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1210 bool failed = false; 1211 for (size_t i = 0; i < delta_file_.size(); ++i) { 1212 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1213 failed = true; 1214 // It should fail at the position that was altered 1215 EXPECT_EQ(delta_file_header_.size() + 0x62, i); 1216 break; 1217 } 1218 } 1219 EXPECT_TRUE(failed); 1220 // The decoder should not create more target bytes than were expected. 1221 EXPECT_GE(expected_target_.size(), output_.size()); 1222 } 1223 1224 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeInvalid) { 1225 WriteInvalidVarintAtOffset(0x5F, 1); 1226 decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1227 bool failed = false; 1228 for (size_t i = 0; i < delta_file_.size(); ++i) { 1229 if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1230 failed = true; 1231 // It should fail at the position that was altered 1232 EXPECT_EQ(delta_file_header_.size() + 0x63, i); 1233 break; 1234 } 1235 } 1236 EXPECT_TRUE(failed); 1237 // The decoder should not create more target bytes than were expected. 1238 EXPECT_GE(expected_target_.size(), output_.size()); 1239 } 1240 1241 } // namespace open_vcdiff 1242