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 42namespace open_vcdiff { 43 44// Test headers, valid and invalid. 45 46TEST_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 55TEST_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 64TEST_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 73TEST_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 82TEST_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 91TEST_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 100TEST_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 111TEST_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 121TEST_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(). 142TEST_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 152TEST_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 163TEST_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 173TEST_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 183TEST_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 192TEST_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. 205TEST_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. 221TEST_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 241TEST_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 253TEST_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 262TEST_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 271TEST_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 280TEST_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 289TEST_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 298TEST_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 307TEST_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 319TEST_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 328TEST_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 337TEST_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 346TEST_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 358TEST_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 367TEST_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 376TEST_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 385TEST_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 394TEST_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 403TEST_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 412TEST_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 424TEST_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 433TEST_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 442TEST_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 451TEST_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 460TEST_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 469TEST_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)) 480TEST_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 513TEST_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 552typedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte; 553 554// Test headers, valid and invalid. 555 556TEST_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 565TEST_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 575TEST_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 591TEST_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 607TEST_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 624TEST_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 633TEST_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 644TEST_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 662TEST_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 689TEST_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 699TEST_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 709TEST_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 723TEST_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. 741TEST_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. 762TEST_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 787TEST_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 807TEST_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. 832TEST_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 847TEST_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 862TEST_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 877TEST_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 894TEST_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 911TEST_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 928TEST_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 948TEST_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 965TEST_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 982TEST_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 999TEST_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. 1024TEST_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 1039TEST_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 1054TEST_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 1069TEST_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 1086TEST_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 1103TEST_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 1120TEST_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. 1145TEST_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 1160TEST_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 1175TEST_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 1190TEST_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 1207TEST_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 1224TEST_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