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