Home | History | Annotate | Download | only in src
      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