text: // Copyright 2008 Google Inc.
  // Author: Lincoln Smith
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //      http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  #include <config.h>
  #include "google/vcdecoder.h"
  #include "testing.h"
  #include "vcdecoder_test.h"
  #include "vcdiff_defs.h"  // VCD_SOURCE
  
  namespace open_vcdiff {
  
  // These are the same tests as for VCDiffStandardDecoderTest, with the added
  // complication that instead of calling DecodeChunk() once with the entire data
  // set, DecodeChunk() is called once for each byte of input.  This is intended
  // to shake out any bugs with rewind and resume while parsing chunked data.
  
  typedef VCDiffStandardDecoderTest VCDiffStandardDecoderTestByteByByte;
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DecodeHeaderOnly) {
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_header_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_header_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, Decode) {
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DecodeNoVcdTarget) {
    decoder_.SetAllowVcdTarget(false);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  // Remove one byte from the length of the chunk to process, and
  // verify that an error is returned for FinishDecoding().
  TEST_F(VCDiffStandardDecoderTestByteByByte, FinishAfterDecodingPartialWindow) {
    delta_file_.resize(delta_file_.size() - 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_FALSE(decoder_.FinishDecoding());
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         FinishAfterDecodingPartialWindowHeader) {
    delta_file_.resize(delta_file_header_.size()
                         + delta_window_header_.size() - 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_FALSE(decoder_.FinishDecoding());
    EXPECT_EQ("", output_);
  }
  
  // If we add a checksum to a standard-format delta file (without using format
  // extensions), it will be interpreted as random bytes inserted into the middle
  // of the file.  The decode operation should fail, but where exactly it fails is
  // undefined.
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         StandardFormatDoesNotSupportChecksum) {
    ComputeAndAddChecksum();
    InitializeDeltaFile();
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetMatchesWindowSizeLimit) {
    decoder_.SetMaximumTargetWindowSize(expected_target_.size());
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetMatchesFileSizeLimit) {
    decoder_.SetMaximumTargetFileSize(expected_target_.size());
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetExceedsWindowSizeLimit) {
    decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetExceedsFileSizeLimit) {
    decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  // Fuzz bits to make sure decoder does not violently crash.
  // This test has no expected behavior except that no crashes should occur.
  // In some cases, changing bits will still decode to the correct target;
  // for example, changing unused bits within a bitfield.
  TEST_F(VCDiffStandardDecoderTestByteByByte, FuzzBits) {
    while (FuzzOneByteInDeltaFile()) {
      decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
      bool failed = false;
      for (size_t i = 0; i < delta_file_.size(); ++i) {
        if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
          failed = true;
          break;
        }
      }
      if (!failed) {
        decoder_.FinishDecoding();
      }
      // The decoder should not create more target bytes than were expected.
      EXPECT_GE(expected_target_.size(), output_.size());
      InitializeDeltaFile();
      output_.clear();
    }
  }
  
  // Change each element of the delta file window to an erroneous value
  // and make sure it's caught as an error.
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         WinIndicatorHasBothSourceAndTarget) {
    delta_file_[delta_file_header_.size()] = VCD_SOURCE + VCD_TARGET;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail at the position that was altered
        EXPECT_EQ(delta_file_header_.size(), i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, OkayToSetUpperBitsOfWinIndicator) {
    // It is not an error to set any of the other bits in Win_Indicator
    // besides VCD_SOURCE and VCD_TARGET.
    delta_file_[delta_file_header_.size()] = 0xFD;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         CopyInstructionsShouldFailIfNoSourceSegment) {
    // Replace the Win_Indicator and the source size and source offset with a
    // single 0 byte (a Win_Indicator for a window with no source segment.)
    delta_window_header_.replace(0, 4, "\0", 1);
    InitializeDeltaFile();
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // The first COPY instruction should fail.  With the standard format,
        // it may need to see the whole delta window before knowing that it is
        // invalid.
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         SourceSegmentSizeExceedsDictionarySize) {
    ++delta_file_[delta_file_header_.size() + 2];  // increment size
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment size
        EXPECT_EQ(delta_file_header_.size() + 2, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentSizeMaxInt) {
    WriteMaxVarintAtOffset(1, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment size
        EXPECT_EQ(delta_file_header_.size() + 5, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentSizeNegative) {
    WriteNegativeVarintAtOffset(1, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment size
        EXPECT_EQ(delta_file_header_.size() + 4, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentSizeInvalid) {
    WriteInvalidVarintAtOffset(1, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment size
        EXPECT_GE(delta_file_header_.size() + 6, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         SourceSegmentEndExceedsDictionarySize) {
    ++delta_file_[delta_file_header_.size() + 3];  // increment start pos
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment end
        EXPECT_EQ(delta_file_header_.size() + 3, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentPosMaxInt) {
    WriteMaxVarintAtOffset(3, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment pos
        EXPECT_EQ(delta_file_header_.size() + 7, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentPosNegative) {
    WriteNegativeVarintAtOffset(3, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment pos
        EXPECT_EQ(delta_file_header_.size() + 6, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentPosInvalid) {
    WriteInvalidVarintAtOffset(3, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the source segment pos
        EXPECT_GE(delta_file_header_.size() + 8, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthZero) {
    delta_file_[delta_file_header_.size() + 4] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 4];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 4];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthMaxInt) {
    WriteMaxVarintAtOffset(4, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail before finishing the window header
        EXPECT_GE(delta_file_header_.size() + delta_window_header_.size() + 4,
                  i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthNegative) {
    WriteNegativeVarintAtOffset(4, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the delta encoding length
        EXPECT_EQ(delta_file_header_.size() + 7, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthInvalid) {
    WriteInvalidVarintAtOffset(4, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the delta encoding length
        EXPECT_GE(delta_file_header_.size() + 9, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeZero) {
    static const char zero_size[] = { 0x00 };
    delta_file_.replace(delta_file_header_.size() + 5, 2, zero_size, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 6];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 6];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeMaxInt) {
    WriteMaxVarintAtOffset(5, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the target window size
        EXPECT_EQ(delta_file_header_.size() + 9, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeNegative) {
    WriteNegativeVarintAtOffset(5, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the target window size
        EXPECT_EQ(delta_file_header_.size() + 8, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeInvalid) {
    WriteInvalidVarintAtOffset(5, 2);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the target window size
        EXPECT_GE(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         OkayToSetUpperBitsOfDeltaIndicator) {
    delta_file_[delta_file_header_.size() + 7] = 0xF8;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
    }
    EXPECT_TRUE(decoder_.FinishDecoding());
    EXPECT_EQ(expected_target_, output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, DataCompressionNotSupported) {
    delta_file_[delta_file_header_.size() + 7] = 0x01;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the delta indicator
        EXPECT_EQ(delta_file_header_.size() + 7, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte,
         InstructionCompressionNotSupported) {
    delta_file_[delta_file_header_.size() + 7] = 0x02;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the delta indicator
        EXPECT_EQ(delta_file_header_.size() + 7, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddressCompressionNotSupported) {
    delta_file_[delta_file_header_.size() + 7] = 0x04;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the delta indicator
        EXPECT_EQ(delta_file_header_.size() + 7, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeZero) {
    delta_file_[delta_file_header_.size() + 8] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 8];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 8];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeMaxInt) {
    WriteMaxVarintAtOffset(8, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail before finishing the window header
        EXPECT_GE(delta_file_header_.size() + delta_window_header_.size() + 4,
                  i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeNegative) {
    WriteNegativeVarintAtOffset(8, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the add/run data segment size
        EXPECT_EQ(delta_file_header_.size() + 11, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeInvalid) {
    WriteInvalidVarintAtOffset(8, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the add/run data segment size
        EXPECT_GE(delta_file_header_.size() + 13, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeZero) {
    delta_file_[delta_file_header_.size() + 9] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 9];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 9];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeMaxInt) {
    WriteMaxVarintAtOffset(9, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail before finishing the window header
        EXPECT_GE(delta_file_header_.size() + delta_window_header_.size() + 4,
                  i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeNegative) {
    WriteNegativeVarintAtOffset(9, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the instructions segment size
        EXPECT_EQ(delta_file_header_.size() + 12, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeInvalid) {
    WriteInvalidVarintAtOffset(9, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the instructions segment size
        EXPECT_GE(delta_file_header_.size() + 14, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeZero) {
    delta_file_[delta_file_header_.size() + 10] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 10];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 10];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 10, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeMaxInt) {
    WriteMaxVarintAtOffset(10, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 14, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeNegative) {
    WriteNegativeVarintAtOffset(10, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_EQ(delta_file_header_.size() + 13, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeInvalid) {
    WriteInvalidVarintAtOffset(10, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        // It should fail after decoding the copy address segment size
        EXPECT_GE(delta_file_header_.size() + 15, i);
        break;
      }
    }
    EXPECT_TRUE(failed);
    EXPECT_EQ("", output_);
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsEndEarly) {
    --delta_file_[delta_file_header_.size() + 9];
    ++delta_file_[delta_file_header_.size() + 10];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  // From this point on, the tests should also be run against the interleaved
  // format.
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyMoreThanExpectedTarget) {
    delta_file_[delta_file_header_.size() + 0x70] =
        FirstByteOfStringLength(kExpectedTarget);
    delta_file_[delta_file_header_.size() + 0x71] =
        SecondByteOfStringLength(kExpectedTarget) + 1;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeZero) {
    delta_file_[delta_file_header_.size() + 0x70] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 0x70];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 0x70];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeMaxInt) {
    WriteMaxVarintAtOffset(0x70, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeNegative) {
    WriteNegativeVarintAtOffset(0x70, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopySizeInvalid) {
    WriteInvalidVarintAtOffset(0x70, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressBeyondHereAddress) {
    delta_file_[delta_file_header_.size() + 0x7B] =
        FirstByteOfStringLength(kDictionary);
    delta_file_[delta_file_header_.size() + 0x7C] =
        SecondByteOfStringLength(kDictionary);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressMaxInt) {
    WriteMaxVarintAtOffset(0x7B, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressNegative) {
    WriteNegativeVarintAtOffset(0x70, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressInvalid) {
    WriteInvalidVarintAtOffset(0x70, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddMoreThanExpectedTarget) {
    delta_file_[delta_file_header_.size() + 0x72] =
        FirstByteOfStringLength(kExpectedTarget);
    delta_file_[delta_file_header_.size() + 0x73] =
        SecondByteOfStringLength(kExpectedTarget) + 1;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeZero) {
    delta_file_[delta_file_header_.size() + 0x72] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 0x72];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 0x72];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeMaxInt) {
    WriteMaxVarintAtOffset(0x72, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeNegative) {
    WriteNegativeVarintAtOffset(0x72, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, AddSizeInvalid) {
    WriteInvalidVarintAtOffset(0x72, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunMoreThanExpectedTarget) {
    delta_file_[delta_file_header_.size() + 0x78] =
        FirstByteOfStringLength(kExpectedTarget);
    delta_file_[delta_file_header_.size() + 0x79] =
        SecondByteOfStringLength(kExpectedTarget) + 1;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeZero) {
    delta_file_[delta_file_header_.size() + 0x78] = 0;
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeTooLargeByOne) {
    ++delta_file_[delta_file_header_.size() + 0x78];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeTooSmallByOne) {
    --delta_file_[delta_file_header_.size() + 0x78];
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeMaxInt) {
    WriteMaxVarintAtOffset(0x78, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeNegative) {
    WriteNegativeVarintAtOffset(0x78, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  TEST_F(VCDiffStandardDecoderTestByteByByte, RunSizeInvalid) {
    WriteInvalidVarintAtOffset(0x78, 1);
    decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
    bool failed = false;
    for (size_t i = 0; i < delta_file_.size(); ++i) {
      if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
        failed = true;
        break;
      }
    }
    EXPECT_TRUE(failed);
    // The decoder should not create more target bytes than were expected.
    EXPECT_GE(expected_target_.size(), output_.size());
  }
  
  }  // namespace open_vcdiff
  