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 39 namespace open_vcdiff { 40 41 // Test headers, valid and invalid. 42 43 TEST_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 52 TEST_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 61 TEST_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 70 TEST_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 79 TEST_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 88 TEST_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 97 TEST_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 108 TEST_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 118 TEST_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(). 139 TEST_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 149 TEST_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 160 TEST_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 170 TEST_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 180 TEST_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 189 TEST_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. 202 TEST_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. 218 TEST_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 238 TEST_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 250 TEST_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 259 TEST_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 268 TEST_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 277 TEST_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 286 TEST_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 295 TEST_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 304 TEST_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 316 TEST_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 325 TEST_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 334 TEST_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 343 TEST_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 355 TEST_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 364 TEST_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 373 TEST_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 382 TEST_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 391 TEST_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 400 TEST_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 409 TEST_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 421 TEST_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 430 TEST_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 439 TEST_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 448 TEST_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 457 TEST_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 466 TEST_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)) 477 TEST_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 510 TEST_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 549 typedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte; 550 551 // Test headers, valid and invalid. 552 553 TEST_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 562 TEST_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 572 TEST_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 588 TEST_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 604 TEST_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 621 TEST_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 630 TEST_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 641 TEST_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 659 TEST_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 686 TEST_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 696 TEST_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 706 TEST_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 720 TEST_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. 738 TEST_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. 759 TEST_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 784 TEST_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 804 TEST_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. 829 TEST_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 844 TEST_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 859 TEST_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 874 TEST_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 891 TEST_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 908 TEST_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 925 TEST_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 945 TEST_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 962 TEST_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 979 TEST_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 996 TEST_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. 1021 TEST_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 1036 TEST_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 1051 TEST_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 1066 TEST_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 1083 TEST_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 1100 TEST_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 1117 TEST_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. 1142 TEST_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 1157 TEST_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 1172 TEST_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 1187 TEST_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 1204 TEST_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 1221 TEST_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