Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: sdch/open_vcdiff/depot/opensource/open-vcdiff/src/vcdecoder_test.cc

Issue 5203: Transition to pulling open-vcdiff from repository, instead of using snapshot... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdch/open_vcdiff/depot/opensource/open-vcdiff/src/vcdecoder_test.cc
===================================================================
--- sdch/open_vcdiff/depot/opensource/open-vcdiff/src/vcdecoder_test.cc (revision 2678)
+++ sdch/open_vcdiff/depot/opensource/open-vcdiff/src/vcdecoder_test.cc (working copy)
@@ -1,4436 +0,0 @@
-// 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 <cstdlib> // free, posix_memalign
-#include <cstring> // memcpy
-#include <string>
-#include "checksum.h"
-#include "codetable.h"
-#include "testing.h"
-#include "varint_bigendian.h"
-#include "vcdiff_defs.h"
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif // HAVE_MALLOC_H
-
-#ifdef HAVE_SYS_MMAN_H
-#define _XOPEN_SOURCE 600 // posix_memalign
-#include <sys/mman.h> // mprotect
-#endif // HAVE_SYS_MMAN_H
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // getpagesize
-#endif // HAVE_UNISTD_H
-
-namespace open_vcdiff {
-namespace {
-
-using std::string;
-
-// A base class used for all the decoder tests. Most tests use the same
-// dictionary and target and construct the delta file in the same way.
-// Those elements are provided as string members and can be modified or
-// overwritten by each specific decoder test as needed.
-class VCDiffDecoderTest : public testing::Test {
- protected:
- static const char kStandardFileHeader[];
- static const char kInterleavedFileHeader[];
- static const char kDictionary[];
- static const char kExpectedTarget[];
- static const char kExpectedAnnotatedTarget[];
-
- VCDiffDecoderTest();
-
- virtual ~VCDiffDecoderTest() {}
-
- virtual void SetUp();
-
- // This function is called by SetUp(). It populates delta_file_ with the
- // concatenated delta file header, delta window header, and delta window
- // body, plus (if UseChecksum() is true) the corresponding checksum.
- // It can be called again by a test that has modified the contents of
- // delta_file_ and needs to restore them to their original state.
- virtual void InitializeDeltaFile();
-
- // This function adds an Adler32 checksum to the delta window header.
- void AddChecksum(VCDChecksum checksum);
-
- // This function computes the Adler32 checksum for the expected target
- // and adds it to the delta window header.
- void ComputeAndAddChecksum();
-
- // Write the maximum expressible positive 32-bit VarintBE
- // (0x7FFFFFFF) at the given offset in the delta window.
- void WriteMaxVarintAtOffset(int offset, int bytes_to_replace);
-
- // Write a negative 32-bit VarintBE (0x80000000) at the given offset
- // in the delta window.
- void WriteNegativeVarintAtOffset(int offset, int bytes_to_replace);
-
- // Write a VarintBE that has too many continuation bytes
- // at the given offset in the delta window.
- void WriteInvalidVarintAtOffset(int offset, int bytes_to_replace);
-
- // This function iterates through a list of fuzzers (bit masks used to corrupt
- // bytes) and through positions in the delta file. Each time it is called, it
- // attempts to corrupt a different byte in delta_file_ in a different way. If
- // successful, it returns true. Once it exhausts the list of fuzzers and of
- // byte positions in delta_file_, it returns false.
- bool FuzzOneByteInDeltaFile();
-
- // Assuming the length of the given string can be expressed as a VarintBE
- // of length N, this function returns the byte at position which_byte, where
- // 0 <= which_byte < N.
- static char GetByteFromStringLength(const char* s, int which_byte) {
- char varint_buf[VarintBE<int32_t>::kMaxBytes];
- VarintBE<int32_t>::Encode(static_cast<int32_t>(strlen(s)), varint_buf);
- return varint_buf[which_byte];
- }
-
- // Assuming the length of the given string can be expressed as a one-byte
- // VarintBE, this function returns that byte value.
- static char StringLengthAsByte(const char* s) {
- return GetByteFromStringLength(s, 0);
- }
-
- // Assuming the length of the given string can be expressed as a two-byte
- // VarintBE, this function returns the first byte of its representation.
- static char FirstByteOfStringLength(const char* s) {
- return GetByteFromStringLength(s, 0);
- }
-
- // Assuming the length of the given string can be expressed as a two-byte
- // VarintBE, this function returns the second byte of its representation.
- static char SecondByteOfStringLength(const char* s) {
- return GetByteFromStringLength(s, 1);
- }
-
- VCDiffStreamingDecoder decoder_;
-
- // delta_file_ will be populated by InitializeDeltaFile() using the components
- // delta_file_header_, delta_window_header_, and delta_window_body_.
- string delta_file_;
-
- // This string is not populated during setup, but is used to receive the
- // decoded target file in each test.
- string output_;
-
- // Test fixtures that inherit from VCDiffDecoderTest can set these strings in
- // their constructors to override their default values (which come from
- // kDictionary, kExpectedTarget, etc.)
- string dictionary_;
- string expected_target_;
- string expected_annotated_target_;
-
- // The components that will be used to construct delta_file_.
- string delta_file_header_;
- string delta_window_header_;
- string delta_window_body_;
-
- private:
- // These two counters are used by FuzzOneByteInDeltaFile() to iterate through
- // different ways to corrupt the delta file.
- size_t fuzzer_;
- size_t fuzzed_byte_position_;
-};
-
-const char VCDiffDecoderTest::kStandardFileHeader[] = {
- 0xD6, // 'V' | 0x80
- 0xC3, // 'C' | 0x80
- 0xC4, // 'D' | 0x80
- 0x00, // Draft standard version number
- 0x00 // Hdr_Indicator: no custom code table, no compression
- };
-
-const char VCDiffDecoderTest::kInterleavedFileHeader[] = {
- 0xD6, // 'V' | 0x80
- 0xC3, // 'C' | 0x80
- 0xC4, // 'D' | 0x80
- 'S', // SDCH version code
- 0x00 // Hdr_Indicator: no custom code table, no compression
- };
-
-const char VCDiffDecoderTest::kDictionary[] =
- "\"Just the place for a Snark!\" the Bellman cried,\n"
- "As he landed his crew with care;\n"
- "Supporting each man on the top of the tide\n"
- "By a finger entwined in his hair.\n";
-
-const char VCDiffDecoderTest::kExpectedTarget[] =
- "\"Just the place for a Snark! I have said it twice:\n"
- "That alone should encourage the crew.\n"
- "Just the place for a Snark! I have said it thrice:\n"
- "What I tell you three times is true.\"\n";
-
-const char VCDiffDecoderTest::kExpectedAnnotatedTarget[] =
- "<dmatch>\"Just the place for a Snark!</dmatch>"
- "<literal> I have said it twice:\n"
- "That alone should encourage the crew.\n</literal>"
- "<bmatch>Just the place for a Snark! I have said it t</bmatch>"
- "<literal>hr</literal>"
- "<bmatch>ice:\n</bmatch>"
- "<literal>What I te</literal>"
- "<literal>ll</literal>"
- "<literal> you three times is true.\"\n</literal>";
-
-VCDiffDecoderTest::VCDiffDecoderTest() : fuzzer_(0), fuzzed_byte_position_(0) {
- dictionary_ = kDictionary;
- expected_target_ = kExpectedTarget;
- expected_annotated_target_ = kExpectedAnnotatedTarget;
-}
-
-void VCDiffDecoderTest::SetUp() {
- InitializeDeltaFile();
-}
-
-void VCDiffDecoderTest::InitializeDeltaFile() {
- delta_file_ = delta_file_header_ + delta_window_header_ + delta_window_body_;
-}
-
-void VCDiffDecoderTest::AddChecksum(VCDChecksum checksum) {
- int32_t checksum_as_int32 = static_cast<int32_t>(checksum);
- delta_window_header_[0] |= VCD_CHECKSUM;
- VarintBE<int32_t>::AppendToString(checksum_as_int32, &delta_window_header_);
- // Adjust delta window size to include checksum.
- // This method wouldn't work if adding to the length caused the VarintBE
- // value to spill over into another byte. Luckily, this test data happens
- // not to cause such an overflow.
- delta_window_header_[4] += VarintBE<int32_t>::Length(checksum_as_int32);
-}
-
-void VCDiffDecoderTest::ComputeAndAddChecksum() {
- AddChecksum(ComputeAdler32(expected_target_.data(),
- expected_target_.size()));
-}
-
-// Write the maximum expressible positive 32-bit VarintBE
-// (0x7FFFFFFF) at the given offset in the delta window.
-void VCDiffDecoderTest::WriteMaxVarintAtOffset(int offset,
- int bytes_to_replace) {
- static const char kMaxVarint[] = { 0x87, 0xFF, 0xFF, 0xFF, 0x7F };
- delta_file_.replace(delta_file_header_.size() + offset,
- bytes_to_replace,
- kMaxVarint,
- sizeof(kMaxVarint));
-}
-
-// Write a negative 32-bit VarintBE (0x80000000) at the given offset
-// in the delta window.
-void VCDiffDecoderTest::WriteNegativeVarintAtOffset(int offset,
- int bytes_to_replace) {
- static const char kNegativeVarint[] = { 0x88, 0x80, 0x80, 0x80, 0x00 };
- delta_file_.replace(delta_file_header_.size() + offset,
- bytes_to_replace,
- kNegativeVarint,
- sizeof(kNegativeVarint));
-}
-
-// Write a VarintBE that has too many continuation bytes
-// at the given offset in the delta window.
-void VCDiffDecoderTest::WriteInvalidVarintAtOffset(int offset,
- int bytes_to_replace) {
- static const char kInvalidVarint[] = { 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F };
- delta_file_.replace(delta_file_header_.size() + offset,
- bytes_to_replace,
- kInvalidVarint,
- sizeof(kInvalidVarint));
-}
-
-bool VCDiffDecoderTest::FuzzOneByteInDeltaFile() {
- static const struct Fuzzer {
- char _and;
- char _or;
- char _xor;
- } fuzzers[] = {
- { 0xff, 0x80, 0x00 },
- { 0xff, 0xff, 0x00 },
- { 0xff, 0x00, 0x80 },
- { 0xff, 0x00, 0xff },
- { 0xff, 0x01, 0x00 },
- { 0x7f, 0x00, 0x00 },
- };
-
- for (; fuzzer_ < (sizeof(fuzzers) / sizeof(fuzzers[0])); ++fuzzer_) {
- for (; fuzzed_byte_position_ < delta_file_.size();
- ++fuzzed_byte_position_) {
- char fuzzed_byte = (((delta_file_[fuzzed_byte_position_]
- & fuzzers[fuzzer_]._and)
- | fuzzers[fuzzer_]._or)
- ^ fuzzers[fuzzer_]._xor);
- if (fuzzed_byte != delta_file_[fuzzed_byte_position_]) {
- delta_file_[fuzzed_byte_position_] = fuzzed_byte;
- ++fuzzed_byte_position_;
- return true;
- }
- }
- fuzzed_byte_position_ = 0;
- }
- return false;
-}
-
-// The "standard" decoder test, which decodes a delta file that uses the
-// standard VCDIFF (RFC 3284) format with no extensions.
-class VCDiffStandardDecoderTest : public VCDiffDecoderTest {
- protected:
- VCDiffStandardDecoderTest();
- virtual ~VCDiffStandardDecoderTest() {}
-
- private:
- static const char kWindowHeader[];
- static const char kWindowBody[];
-};
-
-const char VCDiffStandardDecoderTest::kWindowHeader[] = {
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x79, // Length of the delta encoding
- FirstByteOfStringLength(kExpectedTarget), // Size of the target window
- SecondByteOfStringLength(kExpectedTarget),
- 0x00, // Delta_indicator (no compression)
- 0x64, // length of data for ADDs and RUNs
- 0x0C, // length of instructions section
- 0x03 // length of addresses for COPYs
- };
-
-const char VCDiffStandardDecoderTest::kWindowBody[] = {
- // Data for ADDs: 1st section (length 61)
- ' ', 'I', ' ', 'h', 'a', 'v', 'e', ' ', 's', 'a', 'i', 'd', ' ',
- 'i', 't', ' ', 't', 'w', 'i', 'c', 'e', ':', '\n',
- 'T', 'h', 'a', 't', ' ',
- 'a', 'l', 'o', 'n', 'e', ' ', 's', 'h', 'o', 'u', 'l', 'd', ' ',
- 'e', 'n', 'c', 'o', 'u', 'r', 'a', 'g', 'e', ' ',
- 't', 'h', 'e', ' ', 'c', 'r', 'e', 'w', '.', '\n',
- // Data for ADDs: 2nd section (length 2)
- 'h', 'r',
- // Data for ADDs: 3rd section (length 9)
- 'W', 'h', 'a', 't', ' ',
- 'I', ' ', 't', 'e',
- // Data for RUN: 4th section (length 1)
- 'l',
- // Data for ADD: 4th section (length 27)
- ' ', 'y', 'o', 'u', ' ',
- 't', 'h', 'r', 'e', 'e', ' ', 't', 'i', 'm', 'e', 's', ' ', 'i', 's', ' ',
- 't', 'r', 'u', 'e', '.', '\"', '\n',
- // Instructions and sizes (length 13)
- 0x13, // VCD_COPY mode VCD_SELF, size 0
- 0x1C, // Size of COPY (28)
- 0x01, // VCD_ADD size 0
- 0x3D, // Size of ADD (61)
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x2C, // Size of COPY (44)
- 0xCB, // VCD_ADD size 2 + VCD_COPY mode NEAR(1), size 5
- 0x0A, // VCD_ADD size 9
- 0x00, // VCD_RUN size 0
- 0x02, // Size of RUN (2)
- 0x01, // VCD_ADD size 0
- 0x1B, // Size of ADD (27)
- // Addresses for COPYs (length 3)
- 0x00, // Start of dictionary
- 0x58, // HERE mode address for 2nd copy (27+61 back from here_address)
- 0x2D // NEAR(1) mode address for 2nd copy (45 after prior address)
- };
-
-VCDiffStandardDecoderTest::VCDiffStandardDecoderTest() {
- delta_file_header_.assign(kStandardFileHeader, sizeof(kStandardFileHeader));
- delta_window_header_.assign(kWindowHeader, sizeof(kWindowHeader));
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-TEST_F(VCDiffStandardDecoderTest, DecodeHeaderOnly) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
- delta_file_header_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, 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
-// not easy to predict.
-TEST_F(VCDiffStandardDecoderTest, StandardFormatDoesNotSupportChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-// Remove one byte from the length of the chunk to process, and
-// verify that an error is returned for FinishDecoding().
-TEST_F(VCDiffStandardDecoderTest, FinishAfterDecodingPartialWindow) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size() - 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(VCDiffStandardDecoderTest, FinishAfterDecodingPartialWindowHeader) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_header_.size()
- + delta_window_header_.size() - 1,
- &output_));
- EXPECT_FALSE(decoder_.FinishDecoding());
- 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(VCDiffStandardDecoderTest, FuzzBits) {
- while (FuzzOneByteInDeltaFile()) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- if (decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_)) {
- decoder_.FinishDecoding();
- }
- InitializeDeltaFile();
- output_.clear();
- }
-}
-
-TEST_F(VCDiffStandardDecoderTest, CheckAnnotatedOutput) {
- decoder_.EnableAnnotatedOutput();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- string annotated_output;
- decoder_.GetAnnotatedOutput(&annotated_output);
- EXPECT_EQ(expected_annotated_target_, annotated_output);
-}
-
-// Change each element of the delta file window to an erroneous value
-// and make sure it's caught as an error.
-
-TEST_F(VCDiffStandardDecoderTest, WinIndicatorHasBothSourceAndTarget) {
- delta_file_[delta_file_header_.size()] = VCD_SOURCE + VCD_TARGET;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- // The first COPY instruction should fail, so there should be no output
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentSizeExceedsDictionarySize) {
- ++delta_file_[delta_file_header_.size() + 2]; // increment size
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentSizeMaxInt) {
- WriteMaxVarintAtOffset(1, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentSizeNegative) {
- WriteNegativeVarintAtOffset(1, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentSizeInvalid) {
- WriteInvalidVarintAtOffset(1, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentEndExceedsDictionarySize) {
- ++delta_file_[delta_file_header_.size() + 3]; // increment start pos
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentPosMaxInt) {
- WriteMaxVarintAtOffset(3, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentPosNegative) {
- WriteNegativeVarintAtOffset(3, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, SourceSegmentPosInvalid) {
- WriteInvalidVarintAtOffset(3, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthZero) {
- delta_file_[delta_file_header_.size() + 4] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 4];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 4];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthMaxInt) {
- WriteMaxVarintAtOffset(4, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthNegative) {
- WriteNegativeVarintAtOffset(4, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DeltaEncodingLengthInvalid) {
- WriteInvalidVarintAtOffset(4, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, TargetWindowSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 6];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, TargetWindowSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 6];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, TargetWindowSizeMaxInt) {
- WriteMaxVarintAtOffset(5, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, TargetWindowSizeNegative) {
- WriteNegativeVarintAtOffset(5, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, TargetWindowSizeInvalid) {
- WriteInvalidVarintAtOffset(5, 2);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, OkayToSetUpperBitsOfDeltaIndicator) {
- delta_file_[delta_file_header_.size() + 7] = 0xF8;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, DataCompressionNotSupported) {
- delta_file_[delta_file_header_.size() + 7] = 0x01;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionCompressionNotSupported) {
- delta_file_[delta_file_header_.size() + 7] = 0x02;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddressCompressionNotSupported) {
- delta_file_[delta_file_header_.size() + 7] = 0x04;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeZero) {
- delta_file_[delta_file_header_.size() + 8] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 8];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 8];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeMaxInt) {
- WriteMaxVarintAtOffset(8, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeNegative) {
- WriteNegativeVarintAtOffset(8, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddRunDataSizeInvalid) {
- WriteInvalidVarintAtOffset(8, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeZero) {
- delta_file_[delta_file_header_.size() + 9] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 9];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 9];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeMaxInt) {
- WriteMaxVarintAtOffset(9, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeNegative) {
- WriteNegativeVarintAtOffset(9, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsSizeInvalid) {
- WriteInvalidVarintAtOffset(9, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeZero) {
- delta_file_[delta_file_header_.size() + 10] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 10];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 10];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeMaxInt) {
- WriteMaxVarintAtOffset(10, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeNegative) {
- WriteNegativeVarintAtOffset(10, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressSizeInvalid) {
- WriteInvalidVarintAtOffset(10, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, InstructionsEndEarly) {
- --delta_file_[delta_file_header_.size() + 9];
- ++delta_file_[delta_file_header_.size() + 10];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-// From this point on, the tests should also be run against the interleaved
-// format.
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeZero) {
- delta_file_[delta_file_header_.size() + 0x70] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x70];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x70];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeMaxInt) {
- WriteMaxVarintAtOffset(0x70, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeNegative) {
- WriteNegativeVarintAtOffset(0x70, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopySizeInvalid) {
- WriteInvalidVarintAtOffset(0x70, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressMaxInt) {
- WriteMaxVarintAtOffset(0x7B, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressNegative) {
- WriteNegativeVarintAtOffset(0x70, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, CopyAddressInvalid) {
- WriteInvalidVarintAtOffset(0x70, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeZero) {
- delta_file_[delta_file_header_.size() + 0x72] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x72];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x72];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeMaxInt) {
- WriteMaxVarintAtOffset(0x72, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeNegative) {
- WriteNegativeVarintAtOffset(0x72, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, AddSizeInvalid) {
- WriteInvalidVarintAtOffset(0x72, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, 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());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeZero) {
- delta_file_[delta_file_header_.size() + 0x78] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x78];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x78];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeMaxInt) {
- WriteMaxVarintAtOffset(0x78, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeNegative) {
- WriteNegativeVarintAtOffset(0x78, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffStandardDecoderTest, RunSizeInvalid) {
- WriteInvalidVarintAtOffset(0x78, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-// 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_);
-}
-
-// 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());
-}
-
-// 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();
- }
-}
-
-TEST_F(VCDiffStandardDecoderTestByteByByte, CheckAnnotatedOutput) {
- decoder_.EnableAnnotatedOutput();
- 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());
- string annotated_output;
- decoder_.GetAnnotatedOutput(&annotated_output);
- EXPECT_EQ(expected_annotated_target_, annotated_output);
-}
-
-// 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() + 5, 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() + 7, 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() + 8, 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() + 9, 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() + 12, 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() + 13, 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() + 14, 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());
-}
-
-// The "interleaved" decoder test, which decodes a delta file that uses the
-// SDCH extension of interleaving instructions, addresses, and literal data
-// instead of placing them in three separate sections.
-class VCDiffInterleavedDecoderTest : public VCDiffDecoderTest {
- protected:
- VCDiffInterleavedDecoderTest();
- virtual ~VCDiffInterleavedDecoderTest() {}
-
- private:
- static const char kWindowHeader[];
- static const char kWindowBody[];
-};
-
-const char VCDiffInterleavedDecoderTest::kWindowHeader[] = {
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x79, // Length of the delta encoding
- FirstByteOfStringLength(kExpectedTarget), // Size of the target window
- SecondByteOfStringLength(kExpectedTarget),
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs (unused)
- 0x73, // length of interleaved section
- 0x00 // length of addresses for COPYs (unused)
- };
-
-const char VCDiffInterleavedDecoderTest::kWindowBody[] = {
- 0x13, // VCD_COPY mode VCD_SELF, size 0
- 0x1C, // Size of COPY (28)
- 0x00, // Address of COPY: Start of dictionary
- 0x01, // VCD_ADD size 0
- 0x3D, // Size of ADD (61)
- // Data for ADD (length 61)
- ' ', 'I', ' ', 'h', 'a', 'v', 'e', ' ', 's', 'a', 'i', 'd', ' ',
- 'i', 't', ' ', 't', 'w', 'i', 'c', 'e', ':', '\n',
- 'T', 'h', 'a', 't', ' ',
- 'a', 'l', 'o', 'n', 'e', ' ', 's', 'h', 'o', 'u', 'l', 'd', ' ',
- 'e', 'n', 'c', 'o', 'u', 'r', 'a', 'g', 'e', ' ',
- 't', 'h', 'e', ' ', 'c', 'r', 'e', 'w', '.', '\n',
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x2C, // Size of COPY (44)
- 0x58, // HERE mode address (27+61 back from here_address)
- 0xCB, // VCD_ADD size 2 + VCD_COPY mode NEAR(1), size 5
- // Data for ADDs: 2nd section (length 2)
- 'h', 'r',
- 0x2D, // NEAR(1) mode address (45 after prior address)
- 0x0A, // VCD_ADD size 9
- // Data for ADDs: 3rd section (length 9)
- 'W', 'h', 'a', 't', ' ',
- 'I', ' ', 't', 'e',
- 0x00, // VCD_RUN size 0
- 0x02, // Size of RUN (2)
- // Data for RUN: 4th section (length 1)
- 'l',
- 0x01, // VCD_ADD size 0
- 0x1B, // Size of ADD (27)
- // Data for ADD: 4th section (length 27)
- ' ', 'y', 'o', 'u', ' ',
- 't', 'h', 'r', 'e', 'e', ' ', 't', 'i', 'm', 'e', 's', ' ', 'i', 's', ' ',
- 't', 'r', 'u', 'e', '.', '\"', '\n'
- };
-
-VCDiffInterleavedDecoderTest::VCDiffInterleavedDecoderTest() {
- delta_file_header_.assign(kInterleavedFileHeader,
- sizeof(kInterleavedFileHeader));
- delta_window_header_.assign(kWindowHeader, sizeof(kWindowHeader));
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-// Test headers, valid and invalid.
-
-TEST_F(VCDiffInterleavedDecoderTest, DecodeHeaderOnly) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
- delta_file_header_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, PartialHeaderNotEnough) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
- delta_file_header_.size() - 2,
- &output_));
- EXPECT_FALSE(decoder_.FinishDecoding());
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, BadMagicNumber) {
- delta_file_[1] = 'Q' | 0x80;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, BadVersionNumber) {
- delta_file_[3] = 0x01;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, SecondaryCompressionNotSupported) {
- delta_file_[4] = 0x01;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, ChecksumDoesNotMatch) {
- AddChecksum(0xBADBAD);
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-// Remove one byte from the length of the chunk to process, and
-// verify that an error is returned for FinishDecoding().
-TEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindow) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size() - 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(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindowHeader) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_header_.size()
- + delta_window_header_.size() - 1,
- &output_));
- EXPECT_FALSE(decoder_.FinishDecoding());
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// 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(VCDiffInterleavedDecoderTest, FuzzBits) {
- while (FuzzOneByteInDeltaFile()) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- if (decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_)) {
- decoder_.FinishDecoding();
- }
- InitializeDeltaFile();
- output_.clear();
- }
-}
-
-// If a checksum is present, then fuzzing any of the bits may produce an error,
-// but it should not result in an incorrect target being produced without
-// an error.
-TEST_F(VCDiffInterleavedDecoderTest, FuzzBitsWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- while (FuzzOneByteInDeltaFile()) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- if (decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_)) {
- if (decoder_.FinishDecoding()) {
- // Decoding succeeded. Make sure the correct target was produced.
- EXPECT_EQ(expected_target_, output_);
- }
- } else {
- EXPECT_EQ("", output_);
- }
- InitializeDeltaFile();
- output_.clear();
- }
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CheckAnnotatedOutput) {
- decoder_.EnableAnnotatedOutput();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- string annotated_output;
- decoder_.GetAnnotatedOutput(&annotated_output);
- EXPECT_EQ(expected_annotated_target_, annotated_output);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopyMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x0C] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x0D] =
- SecondByteOfStringLength(kExpectedTarget) + 1;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeZero) {
- delta_file_[delta_file_header_.size() + 0x0C] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x0C];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x0C];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeMaxInt) {
- WriteMaxVarintAtOffset(0x0C, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeNegative) {
- WriteNegativeVarintAtOffset(0x0C, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopySizeInvalid) {
- WriteInvalidVarintAtOffset(0x0C, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopyAddressBeyondHereAddress) {
- delta_file_[delta_file_header_.size() + 0x0D] =
- FirstByteOfStringLength(kDictionary);
- delta_file_[delta_file_header_.size() + 0x0E] =
- SecondByteOfStringLength(kDictionary);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopyAddressMaxInt) {
- WriteMaxVarintAtOffset(0x0D, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopyAddressNegative) {
- WriteNegativeVarintAtOffset(0x0D, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, CopyAddressInvalid) {
- WriteInvalidVarintAtOffset(0x0D, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x0F] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x10] =
- SecondByteOfStringLength(kExpectedTarget) + 1;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeZero) {
- delta_file_[delta_file_header_.size() + 0x0F] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x0F];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x0F];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeMaxInt) {
- WriteMaxVarintAtOffset(0x0F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeNegative) {
- WriteNegativeVarintAtOffset(0x0F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, AddSizeInvalid) {
- WriteInvalidVarintAtOffset(0x0F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x5F] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x60] =
- SecondByteOfStringLength(kExpectedTarget) + 1;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeZero) {
- delta_file_[delta_file_header_.size() + 0x5F] = 0;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x5F];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x5F];
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeMaxInt) {
- WriteMaxVarintAtOffset(0x5F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeNegative) {
- WriteNegativeVarintAtOffset(0x5F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, RunSizeInvalid) {
- WriteInvalidVarintAtOffset(0x5F, 1);
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-#if defined(HAVE_MPROTECT) && \
- (defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN))
-TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastEndOfBuffer) {
- // Allocate two memory pages.
- const int page_size = getpagesize();
- void* two_pages = NULL;
-#ifdef HAVE_POSIX_MEMALIGN
- posix_memalign(&two_pages, page_size, 2 * page_size);
-#else // !HAVE_POSIX_MEMALIGN
- two_pages = memalign(page_size, 2 * page_size);
-#endif // HAVE_POSIX_MEMALIGN
- char* const first_page = reinterpret_cast<char*>(two_pages);
- char* const second_page = first_page + page_size;
-
- // Place the delta string at the end of the first page.
- char* delta_with_guard = second_page - delta_file_.size();
- memcpy(delta_with_guard, delta_file_.data(), delta_file_.size());
-
- // Make the second page unreadable.
- mprotect(second_page, page_size, PROT_NONE);
-
- // Now perform the decode operation, which will cause a segmentation fault
- // if it reads past the end of the buffer.
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard,
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-
- // Undo the mprotect.
- mprotect(second_page, page_size, PROT_READ|PROT_WRITE);
- free(two_pages);
-}
-
-TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastBeginningOfBuffer) {
- // Allocate two memory pages.
- const int page_size = getpagesize();
- void* two_pages = NULL;
-#ifdef HAVE_POSIX_MEMALIGN
- posix_memalign(&two_pages, page_size, 2 * page_size);
-#else // !HAVE_POSIX_MEMALIGN
- two_pages = memalign(page_size, 2 * page_size);
-#endif // HAVE_POSIX_MEMALIGN
- char* const first_page = reinterpret_cast<char*>(two_pages);
- char* const second_page = first_page + page_size;
-
- // Make the first page unreadable.
- mprotect(first_page, page_size, PROT_NONE);
-
- // Place the delta string at the beginning of the second page.
- char* delta_with_guard = second_page;
- memcpy(delta_with_guard, delta_file_.data(), delta_file_.size());
-
- // Now perform the decode operation, which will cause a segmentation fault
- // if it reads past the beginning of the buffer.
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard,
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-
- // Undo the mprotect.
- mprotect(first_page, page_size, PROT_READ|PROT_WRITE);
- free(two_pages);
-}
-#endif // HAVE_MPROTECT && (HAVE_MEMALIGN || HAVE_POSIX_MEMALIGN)
-
-// These are the same tests as for VCDiffInterleavedDecoderTest, 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 VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte;
-
-// Test headers, valid and invalid.
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, 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(VCDiffInterleavedDecoderTestByteByByte, PartialHeaderNotEnough) {
- delta_file_.resize(delta_file_header_.size() - 2);
- 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_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadMagicNumber) {
- delta_file_[1] = 'Q' | 0x80;
- 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_)) {
- // It should fail at the position that was altered
- EXPECT_EQ(1U, i);
- failed = true;
- break;
- }
- }
- EXPECT_TRUE(failed);
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadVersionNumber) {
- delta_file_[3] = 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 at the position that was altered
- EXPECT_EQ(3U, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte,
- SecondaryCompressionNotSupported) {
- delta_file_[4] = 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 at the position that was altered
- EXPECT_EQ(4U, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, 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(VCDiffInterleavedDecoderTestByteByByte, DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- 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(VCDiffInterleavedDecoderTestByteByByte, ChecksumDoesNotMatch) {
- AddChecksum(0xBADBAD);
- 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;
- // It should fail after decoding the entire delta file
- EXPECT_EQ(delta_file_.size() - 1, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// 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(VCDiffInterleavedDecoderTestByteByByte, 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();
- }
- InitializeDeltaFile();
- output_.clear();
- }
-}
-
-// If a checksum is present, then fuzzing any of the bits may produce an error,
-// but it should not result in an incorrect target being produced without
-// an error.
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBitsWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- 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) {
- if (decoder_.FinishDecoding()) {
- // Decoding succeeded. Make sure the correct target was produced.
- EXPECT_EQ(expected_target_, output_);
- }
- }
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
- InitializeDeltaFile();
- output_.clear();
- }
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CheckAnnotatedOutput) {
- decoder_.EnableAnnotatedOutput();
- 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());
- string annotated_output;
- decoder_.GetAnnotatedOutput(&annotated_output);
- EXPECT_EQ(expected_annotated_target_, annotated_output);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte,
- 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.
- EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() + 2, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x0C] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x0D] =
- 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;
- // It should fail at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x0D, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// A COPY instruction with an explicit size of 0 is not illegal according to the
-// standard, although it is inefficient and should not be generated by any
-// reasonable encoder. Changing the size of a COPY instruction to zero will
-// cause a failure because the generated target window size will not match the
-// expected target size.
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeZero) {
- delta_file_[delta_file_header_.size() + 0x0C] = 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(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x0C];
- 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(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x0C];
- 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(VCDiffInterleavedDecoderTestByteByByte, CopySizeMaxInt) {
- WriteMaxVarintAtOffset(0x0C, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x10, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeNegative) {
- WriteNegativeVarintAtOffset(0x0C, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x10, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeInvalid) {
- WriteInvalidVarintAtOffset(0x0C, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x10, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressBeyondHereAddress) {
- delta_file_[delta_file_header_.size() + 0x0D] =
- FirstByteOfStringLength(kDictionary);
- delta_file_[delta_file_header_.size() + 0x0E] =
- 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;
- // It should fail at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x0E, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressMaxInt) {
- WriteMaxVarintAtOffset(0x0D, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x11, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressNegative) {
- WriteNegativeVarintAtOffset(0x0D, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x11, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressInvalid) {
- WriteInvalidVarintAtOffset(0x0D, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x11, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x0F] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x10] =
- 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;
- // It should fail at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x10, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// An ADD instruction with an explicit size of 0 is not illegal according to the
-// standard, although it is inefficient and should not be generated by any
-// reasonable encoder. Changing the size of an ADD instruction to zero will
-// cause a failure because the generated target window size will not match the
-// expected target size.
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeZero) {
- delta_file_[delta_file_header_.size() + 0x0F] = 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(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x0F];
- 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(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x0F];
- 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(VCDiffInterleavedDecoderTestByteByByte, AddSizeMaxInt) {
- WriteMaxVarintAtOffset(0x0F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x13, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeNegative) {
- WriteNegativeVarintAtOffset(0x0F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x13, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeInvalid) {
- WriteInvalidVarintAtOffset(0x0F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x13, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunMoreThanExpectedTarget) {
- delta_file_[delta_file_header_.size() + 0x5F] =
- FirstByteOfStringLength(kExpectedTarget);
- delta_file_[delta_file_header_.size() + 0x60] =
- 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;
- // It should fail at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x60, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// A RUN instruction with an explicit size of 0 is not illegal according to the
-// standard, although it is inefficient and should not be generated by any
-// reasonable encoder. Changing the size of a RUN instruction to zero will
-// cause a failure because the generated target window size will not match the
-// expected target size.
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeZero) {
- delta_file_[delta_file_header_.size() + 0x5F] = 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(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooLargeByOne) {
- ++delta_file_[delta_file_header_.size() + 0x5F];
- 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(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooSmallByOne) {
- --delta_file_[delta_file_header_.size() + 0x5F];
- 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(VCDiffInterleavedDecoderTestByteByByte, RunSizeMaxInt) {
- WriteMaxVarintAtOffset(0x5F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x63, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeNegative) {
- WriteNegativeVarintAtOffset(0x5F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x63, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeInvalid) {
- WriteInvalidVarintAtOffset(0x5F, 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 at the position that was altered
- EXPECT_EQ(delta_file_header_.size() + 0x63, i);
- break;
- }
- }
- EXPECT_TRUE(failed);
- // The decoder should not create more target bytes than were expected.
- EXPECT_GE(expected_target_.size(), output_.size());
-}
-
-// Use the interleaved file header with the standard encoding. Should work.
-class VCDiffDecoderInterleavedAllowedButNotUsed
- : public VCDiffStandardDecoderTest {
- public:
- VCDiffDecoderInterleavedAllowedButNotUsed() {
- delta_file_header_.assign(kInterleavedFileHeader,
- sizeof(kInterleavedFileHeader));
- }
- virtual ~VCDiffDecoderInterleavedAllowedButNotUsed() { }
-};
-
-TEST_F(VCDiffDecoderInterleavedAllowedButNotUsed, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffDecoderInterleavedAllowedButNotUsed, DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-typedef VCDiffDecoderInterleavedAllowedButNotUsed
- VCDiffDecoderInterleavedAllowedButNotUsedByteByByte;
-
-TEST_F(VCDiffDecoderInterleavedAllowedButNotUsedByteByByte, 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(VCDiffDecoderInterleavedAllowedButNotUsedByteByByte,
- DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- 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_);
-}
-
-// Use the standard file header with the interleaved encoding. Should fail.
-class VCDiffDecoderInterleavedUsedButNotSupported
- : public VCDiffInterleavedDecoderTest {
- public:
- VCDiffDecoderInterleavedUsedButNotSupported() {
- delta_file_header_.assign(kStandardFileHeader, sizeof(kStandardFileHeader));
- }
- virtual ~VCDiffDecoderInterleavedUsedButNotSupported() { }
-};
-
-TEST_F(VCDiffDecoderInterleavedUsedButNotSupported, DecodeShouldFail) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_EQ("", output_);
-}
-
-TEST_F(VCDiffDecoderInterleavedUsedButNotSupported,
- DecodeByteByByteShouldFail) {
- 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());
-}
-
-// Divides up the standard encoding into eight separate delta file windows.
-// Each delta instruction appears in its own window.
-class VCDiffStandardWindowDecoderTest : public VCDiffDecoderTest {
- protected:
- VCDiffStandardWindowDecoderTest();
- virtual ~VCDiffStandardWindowDecoderTest() {}
-
- private:
- static const char kExpectedAnnotatedTarget[];
- static const char kWindowBody[];
-};
-
-const char VCDiffStandardWindowDecoderTest::kWindowBody[] = {
-// Window 1:
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x08, // Length of the delta encoding
- 0x1C, // Size of the target window (28)
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x02, // length of instructions section
- 0x01, // length of addresses for COPYs
- // No data for ADDs and RUNs
- // Instructions and sizes (length 2)
- 0x13, // VCD_COPY mode VCD_SELF, size 0
- 0x1C, // Size of COPY (28)
- // Addresses for COPYs (length 1)
- 0x00, // Start of dictionary
-// Window 2:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x44, // Length of the delta encoding
- 0x3D, // Size of the target window (61)
- 0x00, // Delta_indicator (no compression)
- 0x3D, // length of data for ADDs and RUNs
- 0x02, // length of instructions section
- 0x00, // length of addresses for COPYs
- // Data for ADD (length 61)
- ' ', 'I', ' ', 'h', 'a', 'v', 'e', ' ', 's', 'a', 'i', 'd', ' ',
- 'i', 't', ' ', 't', 'w', 'i', 'c', 'e', ':', '\n',
- 'T', 'h', 'a', 't', ' ',
- 'a', 'l', 'o', 'n', 'e', ' ', 's', 'h', 'o', 'u', 'l', 'd', ' ',
- 'e', 'n', 'c', 'o', 'u', 'r', 'a', 'g', 'e', ' ',
- 't', 'h', 'e', ' ', 'c', 'r', 'e', 'w', '.', '\n',
- // Instructions and sizes (length 2)
- 0x01, // VCD_ADD size 0
- 0x3D, // Size of ADD (61)
- // No addresses for COPYs
-// Window 3:
- VCD_TARGET, // Win_Indicator: take source from decoded data
- 0x59, // Source segment size: length of data decoded so far
- 0x00, // Source segment position: start of decoded data
- 0x08, // Length of the delta encoding
- 0x2C, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x02, // length of instructions section
- 0x01, // length of addresses for COPYs
- // No data for ADDs and RUNs
- // Instructions and sizes (length 2)
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x2C, // Size of COPY (44)
- // Addresses for COPYs (length 1)
- 0x58, // HERE mode address (27+61 back from here_address)
-// Window 4:
- VCD_TARGET, // Win_Indicator: take source from decoded data
- 0x05, // Source segment size: only 5 bytes needed for this COPY
- 0x2E, // Source segment position: offset for COPY
- 0x09, // Length of the delta encoding
- 0x07, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x02, // length of data for ADDs and RUNs
- 0x01, // length of instructions section
- 0x01, // length of addresses for COPYs
- // Data for ADD (length 2)
- 'h', 'r',
- // Instructions and sizes (length 1)
- 0xA7, // VCD_ADD size 2 + VCD_COPY mode SELF size 5
- // Addresses for COPYs (length 1)
- 0x00, // SELF mode address (start of source segment)
-// Window 5:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x0F, // Length of the delta encoding
- 0x09, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x09, // length of data for ADDs and RUNs
- 0x01, // length of instructions section
- 0x00, // length of addresses for COPYs
- // Data for ADD (length 9)
- 'W', 'h', 'a', 't', ' ', 'I', ' ', 't', 'e',
- // Instructions and sizes (length 1)
- 0x0A, // VCD_ADD size 9
- // No addresses for COPYs
-// Window 6:
- 0x00, // Win_Indicator: No source segment (RUN only)
- 0x08, // Length of the delta encoding
- 0x02, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x01, // length of data for ADDs and RUNs
- 0x02, // length of instructions section
- 0x00, // length of addresses for COPYs
- // Data for RUN (length 1)
- 'l',
- // Instructions and sizes (length 2)
- 0x00, // VCD_RUN size 0
- 0x02, // Size of RUN (2)
- // No addresses for COPYs
-// Window 7:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x22, // Length of the delta encoding
- 0x1B, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x1B, // length of data for ADDs and RUNs
- 0x02, // length of instructions section
- 0x00, // length of addresses for COPYs
- // Data for ADD: 4th section (length 27)
- ' ', 'y', 'o', 'u', ' ',
- 't', 'h', 'r', 'e', 'e', ' ', 't', 'i', 'm', 'e', 's', ' ', 'i', 's', ' ',
- 't', 'r', 'u', 'e', '.', '\"', '\n',
- // Instructions and sizes (length 2)
- 0x01, // VCD_ADD size 0
- 0x1B, // Size of ADD (27)
- // No addresses for COPYs
- };
-
-// The window encoding should produce the same target file as the standard
-// encoding, but the annotated target will be different because some of the
-// <bmatch> tags (copying from the previously decoded data in the current target
-// window) are changed to <dmatch> (copying from the previously decoded data in
-// another target window, which is used as the source window for the current
-// delta window.)
-const char VCDiffStandardWindowDecoderTest::kExpectedAnnotatedTarget[] =
- "<dmatch>\"Just the place for a Snark!</dmatch>"
- "<literal> I have said it twice:\n"
- "That alone should encourage the crew.\n</literal>"
- "<dmatch>Just the place for a Snark! I have said it t</dmatch>"
- "<literal>hr</literal>"
- "<dmatch>ice:\n</dmatch>"
- "<literal>What I te</literal>"
- "<literal>ll</literal>"
- "<literal> you three times is true.\"\n</literal>";
-
-VCDiffStandardWindowDecoderTest::VCDiffStandardWindowDecoderTest() {
- delta_file_header_.assign(kStandardFileHeader, sizeof(kStandardFileHeader));
- expected_annotated_target_.assign(kExpectedAnnotatedTarget);
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-TEST_F(VCDiffStandardWindowDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-// Bug 1287926: If DecodeChunk() stops in the middle of the window header,
-// and the expected size of the current target window is smaller than the
-// cumulative target bytes decoded so far, an underflow occurs and the decoder
-// tries to allocate ~MAX_INT bytes.
-TEST_F(VCDiffStandardWindowDecoderTest, DecodeBreakInFourthWindowHeader) {
- // Parse file header + first two windows.
- const int chunk_1_size = sizeof(kStandardFileHeader) + 83;
- // Parse third window, plus everything up to "Size of the target window" field
- // of fourth window, but do not parse complete header of fourth window.
- const int chunk_2_size = 12 + 5;
- CHECK_EQ(VCD_TARGET, static_cast<unsigned char>(delta_file_[chunk_1_size]));
- CHECK_EQ(0x00, static_cast<int>(delta_file_[chunk_1_size + chunk_2_size]));
- string output_chunk1, output_chunk2, output_chunk3;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[0],
- chunk_1_size,
- &output_chunk1));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[chunk_1_size],
- chunk_2_size,
- &output_chunk2));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[chunk_1_size + chunk_2_size],
- delta_file_.size()
- - (chunk_1_size + chunk_2_size),
- &output_chunk3));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_chunk1 + output_chunk2 + output_chunk3);
-}
-
-TEST_F(VCDiffStandardWindowDecoderTest, DecodeInTwoParts) {
- const size_t delta_file_size = delta_file_.size();
- for (size_t i = 1; i < delta_file_size; i++) {
- string output_chunk1, output_chunk2;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[0],
- i,
- &output_chunk1));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i],
- delta_file_size - i,
- &output_chunk2));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_chunk1 + output_chunk2);
- }
-}
-
-TEST_F(VCDiffStandardWindowDecoderTest, DecodeInThreeParts) {
- const size_t delta_file_size = delta_file_.size();
- for (size_t i = 1; i < delta_file_size - 1; i++) {
- for (size_t j = i + 1; j < delta_file_size; j++) {
- string output_chunk1, output_chunk2, output_chunk3;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[0],
- i,
- &output_chunk1));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i],
- j - i,
- &output_chunk2));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[j],
- delta_file_size - j,
- &output_chunk3));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_,
- output_chunk1 + output_chunk2 + output_chunk3);
- }
- }
-}
-
-typedef VCDiffStandardWindowDecoderTest
- VCDiffStandardWindowDecoderTestByteByByte;
-TEST_F(VCDiffStandardWindowDecoderTestByteByByte, 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_);
-}
-
-// Divides up the interleaved encoding into eight separate delta file windows.
-class VCDiffInterleavedWindowDecoderTest
- : public VCDiffStandardWindowDecoderTest {
- protected:
- VCDiffInterleavedWindowDecoderTest();
- virtual ~VCDiffInterleavedWindowDecoderTest() {}
- private:
- static const char kWindowBody[];
-};
-
-const char VCDiffInterleavedWindowDecoderTest::kWindowBody[] = {
-// Window 1:
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x08, // Length of the delta encoding
- 0x1C, // Size of the target window (28)
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x03, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x13, // VCD_COPY mode VCD_SELF, size 0
- 0x1C, // Size of COPY (28)
- 0x00, // Start of dictionary
-// Window 2:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x44, // Length of the delta encoding
- 0x3D, // Size of the target window (61)
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x3F, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x01, // VCD_ADD size 0
- 0x3D, // Size of ADD (61)
- ' ', 'I', ' ', 'h', 'a', 'v', 'e', ' ', 's', 'a', 'i', 'd', ' ',
- 'i', 't', ' ', 't', 'w', 'i', 'c', 'e', ':', '\n',
- 'T', 'h', 'a', 't', ' ',
- 'a', 'l', 'o', 'n', 'e', ' ', 's', 'h', 'o', 'u', 'l', 'd', ' ',
- 'e', 'n', 'c', 'o', 'u', 'r', 'a', 'g', 'e', ' ',
- 't', 'h', 'e', ' ', 'c', 'r', 'e', 'w', '.', '\n',
-// Window 3:
- VCD_TARGET, // Win_Indicator: take source from decoded data
- 0x59, // Source segment size: length of data decoded so far
- 0x00, // Source segment position: start of decoded data
- 0x08, // Length of the delta encoding
- 0x2C, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x03, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x2C, // Size of COPY (44)
- 0x58, // HERE mode address (27+61 back from here_address)
-// Window 4:
- VCD_TARGET, // Win_Indicator: take source from decoded data
- 0x05, // Source segment size: only 5 bytes needed for this COPY
- 0x2E, // Source segment position: offset for COPY
- 0x09, // Length of the delta encoding
- 0x07, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x04, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0xA7, // VCD_ADD size 2 + VCD_COPY mode SELF, size 5
- 'h', 'r',
- 0x00, // SELF mode address (start of source segment)
-// Window 5:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x0F, // Length of the delta encoding
- 0x09, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x0A, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x0A, // VCD_ADD size 9
- 'W', 'h', 'a', 't', ' ', 'I', ' ', 't', 'e',
-// Window 6:
- 0x00, // Win_Indicator: No source segment (RUN only)
- 0x08, // Length of the delta encoding
- 0x02, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x03, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x00, // VCD_RUN size 0
- 0x02, // Size of RUN (2)
- 'l',
-// Window 7:
- 0x00, // Win_Indicator: No source segment (ADD only)
- 0x22, // Length of the delta encoding
- 0x1B, // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x1D, // length of instructions section
- 0x00, // length of addresses for COPYs
- 0x01, // VCD_ADD size 0
- 0x1B, // Size of ADD (27)
- ' ', 'y', 'o', 'u', ' ',
- 't', 'h', 'r', 'e', 'e', ' ', 't', 'i', 'm', 'e', 's', ' ', 'i', 's', ' ',
- 't', 'r', 'u', 'e', '.', '\"', '\n',
- };
-
-VCDiffInterleavedWindowDecoderTest::VCDiffInterleavedWindowDecoderTest() {
- delta_file_header_.assign(kInterleavedFileHeader,
- sizeof(kInterleavedFileHeader));
- // delta_window_header_ is left blank. All window headers and bodies are
- // lumped together in delta_window_body_. This means that AddChecksum()
- // cannot be used to test the checksum feature.
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-TEST_F(VCDiffInterleavedWindowDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffInterleavedWindowDecoderTest, DecodeInTwoParts) {
- const size_t delta_file_size = delta_file_.size();
- for (size_t i = 1; i < delta_file_size; i++) {
- string output_chunk1, output_chunk2;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[0],
- i,
- &output_chunk1));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i],
- delta_file_size - i,
- &output_chunk2));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_chunk1 + output_chunk2);
- }
-}
-
-TEST_F(VCDiffInterleavedWindowDecoderTest, DecodeInThreeParts) {
- const size_t delta_file_size = delta_file_.size();
- for (size_t i = 1; i < delta_file_size - 1; i++) {
- for (size_t j = i + 1; j < delta_file_size; j++) {
- string output_chunk1, output_chunk2, output_chunk3;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[0],
- i,
- &output_chunk1));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i],
- j - i,
- &output_chunk2));
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[j],
- delta_file_size - j,
- &output_chunk3));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_,
- output_chunk1 + output_chunk2 + output_chunk3);
- }
- }
-}
-
-typedef VCDiffInterleavedWindowDecoderTest
- VCDiffInterleavedWindowDecoderTestByteByByte;
-
-TEST_F(VCDiffInterleavedWindowDecoderTestByteByByte, 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_);
-}
-
-// The original version of VCDiffDecoder did not allow the caller to modify the
-// contents of output_string between calls to DecodeChunk(). That restriction
-// has been removed. Verify that the same result is still produced if the
-// output string is cleared after each call to DecodeChunk(). Use the window
-// encoding because it refers back to the previously decoded target data, which
-// is the feature that would fail if the restriction still applied.
-//
-TEST_F(VCDiffInterleavedWindowDecoderTest, OutputStringCanBeModified) {
- string temp_output;
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- for (size_t i = 0; i < delta_file_.size(); ++i) {
- EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &temp_output));
- output_.append(temp_output);
- temp_output.clear();
- }
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffInterleavedWindowDecoderTest, OutputStringIsPreserved) {
- const string previous_data("Previous data");
- output_ = previous_data;
- 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(previous_data + expected_target_, output_);
-}
-
-// A decode job that tests the ability to COPY across the boundary between
-// source data and target data.
-class VCDiffStandardCrossDecoderTest : public VCDiffDecoderTest {
- protected:
- static const char kExpectedTarget[];
- static const char kExpectedAnnotatedTarget[];
- static const char kWindowHeader[];
- static const char kWindowBody[];
-
- VCDiffStandardCrossDecoderTest();
- virtual ~VCDiffStandardCrossDecoderTest() {}
-};
-
-const char VCDiffStandardCrossDecoderTest::kWindowHeader[] = {
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x15, // Length of the delta encoding
- StringLengthAsByte(kExpectedTarget), // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x07, // length of data for ADDs and RUNs
- 0x06, // length of instructions section
- 0x03 // length of addresses for COPYs
- };
-
-const char VCDiffStandardCrossDecoderTest::kWindowBody[] = {
- // Data for ADD (length 7)
- 'S', 'p', 'i', 'd', 'e', 'r', 's',
- // Instructions and sizes (length 6)
- 0x01, // VCD_ADD size 0
- 0x07, // Size of ADD (7)
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x19, // Size of COPY (25)
- 0x14, // VCD_COPY mode VCD_SELF, size 4
- 0x25, // VCD_COPY mode VCD_HERE, size 5
- // Addresses for COPYs (length 3)
- 0x15, // HERE mode address for 1st copy (21 back from here_address)
- 0x06, // SELF mode address for 2nd copy
- 0x14 // HERE mode address for 3rd copy
- };
-
-const char VCDiffStandardCrossDecoderTest::kExpectedTarget[] =
- "Spiders in his hair.\n"
- "Spiders in the air.\n";
-
-const char VCDiffStandardCrossDecoderTest::kExpectedAnnotatedTarget[] =
- "<literal>Spiders</literal>"
- "<dmatch> in his hair.\n</dmatch>" // crosses source-target boundary
- "<bmatch>Spiders in </bmatch>"
- "<dmatch>the </dmatch>"
- "<bmatch>air.\n</bmatch>";
-
-VCDiffStandardCrossDecoderTest::VCDiffStandardCrossDecoderTest() {
- delta_file_header_.assign(kStandardFileHeader, sizeof(kStandardFileHeader));
- delta_window_header_.assign(kWindowHeader, sizeof(kWindowHeader));
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
- expected_target_.assign(kExpectedTarget);
- expected_annotated_target_.assign(kExpectedAnnotatedTarget);
-}
-
-TEST_F(VCDiffStandardCrossDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-typedef VCDiffStandardCrossDecoderTest VCDiffStandardCrossDecoderTestByteByByte;
-
-TEST_F(VCDiffStandardCrossDecoderTestByteByByte, 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_);
-}
-
-// The same decode job that tests the ability to COPY across the boundary
-// between source data and target data, but using the interleaved format rather
-// than the standard format.
-class VCDiffInterleavedCrossDecoderTest
- : public VCDiffStandardCrossDecoderTest {
- protected:
- VCDiffInterleavedCrossDecoderTest();
- virtual ~VCDiffInterleavedCrossDecoderTest() {}
-
- private:
- static const char kWindowHeader[];
- static const char kWindowBody[];
-};
-
-const char VCDiffInterleavedCrossDecoderTest::kWindowHeader[] = {
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x15, // Length of the delta encoding
- StringLengthAsByte(kExpectedTarget), // Size of the target window
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs
- 0x10, // length of instructions section
- 0x00, // length of addresses for COPYs
- };
-
-const char VCDiffInterleavedCrossDecoderTest::kWindowBody[] = {
- 0x01, // VCD_ADD size 0
- 0x07, // Size of ADD (7)
- // Data for ADD (length 7)
- 'S', 'p', 'i', 'd', 'e', 'r', 's',
- 0x23, // VCD_COPY mode VCD_HERE, size 0
- 0x19, // Size of COPY (25)
- 0x15, // HERE mode address for 1st copy (21 back from here_address)
- 0x14, // VCD_COPY mode VCD_SELF, size 4
- 0x06, // SELF mode address for 2nd copy
- 0x25, // VCD_COPY mode VCD_HERE, size 5
- 0x14 // HERE mode address for 3rd copy
- };
-
-VCDiffInterleavedCrossDecoderTest::VCDiffInterleavedCrossDecoderTest() {
- delta_file_header_.assign(kInterleavedFileHeader,
- sizeof(kInterleavedFileHeader));
- delta_window_header_.assign(kWindowHeader, sizeof(kWindowHeader));
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-TEST_F(VCDiffInterleavedCrossDecoderTest, Decode) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffInterleavedCrossDecoderTest, DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-typedef VCDiffInterleavedCrossDecoderTest
- VCDiffInterleavedCrossDecoderTestByteByByte;
-
-TEST_F(VCDiffInterleavedCrossDecoderTestByteByByte, 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(VCDiffInterleavedCrossDecoderTestByteByByte, DecodeWithChecksum) {
- ComputeAndAddChecksum();
- InitializeDeltaFile();
- 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 using a custom code table and custom cache sizes with interleaved
-// format.
-class VCDiffCustomCodeTableDecoderTest : public VCDiffInterleavedDecoderTest {
- protected:
- static const char kFileHeader[];
- static const char kWindowHeader[];
- static const char kWindowBody[];
- static const char kEncodedCustomCodeTable[];
-
- VCDiffCustomCodeTableDecoderTest();
- virtual ~VCDiffCustomCodeTableDecoderTest() {}
-};
-
-const char VCDiffCustomCodeTableDecoderTest::kFileHeader[] = {
- 0xD6, // 'V' | 0x80
- 0xC3, // 'C' | 0x80
- 0xC4, // 'D' | 0x80
- 'S', // SDCH version code
- 0x02 // Hdr_Indicator: Use custom code table
- };
-
-// Make a custom code table that includes exactly the instructions we need
-// to encode the first test's data without using any explicit length values.
-// Be careful not to replace any existing opcodes that have size 0,
-// to ensure that the custom code table is valid (can express all possible
-// values of inst (also known as instruction type) and mode with size 0.)
-// This encoding uses interleaved format, which is easier to read.
-//
-// Here are the changes to the standard code table:
-// ADD size 2 (opcode 3) => RUN size 2 (inst1[3] = VCD_RUN)
-// ADD size 16 (opcode 17) => ADD size 27 (size1[17] = 27)
-// ADD size 17 (opcode 18) => ADD size 61 (size1[18] = 61)
-// COPY mode 0 size 18 (opcode 34) => COPY mode 0 size 28 (size1[34] = 28)
-// COPY mode 1 size 18 (opcode 50) => COPY mode 1 size 44 (size1[50] = 44)
-//
-const char VCDiffCustomCodeTableDecoderTest::kEncodedCustomCodeTable[] = {
- 0xD6, // 'V' | 0x80
- 0xC3, // 'C' | 0x80
- 0xC4, // 'D' | 0x80
- 'S', // SDCH version code
- 0x00, // Hdr_Indicator: no custom code table, no compression
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- (sizeof(VCDiffCodeTableData) >> 7) | 0x80, // First byte of table length
- sizeof(VCDiffCodeTableData) & 0x7F, // Second byte of table length
- 0x00, // Source segment position: start of default code table
- 0x1F, // Length of the delta encoding
- (sizeof(VCDiffCodeTableData) >> 7) | 0x80, // First byte of table length
- sizeof(VCDiffCodeTableData) & 0x7F, // Second byte of table length
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs (unused)
- 0x19, // length of interleaved section
- 0x00, // length of addresses for COPYs (unused)
- 0x05, // VCD_ADD size 4
- // Data for ADD (length 4)
- VCD_RUN, VCD_ADD, VCD_ADD, VCD_RUN,
- 0x13, // VCD_COPY mode VCD_SELF size 0
- 0x84, // Size of copy: upper bits (512 - 4 + 17 = 525)
- 0x0D, // Size of copy: lower bits
- 0x04, // Address of COPY
- 0x03, // VCD_ADD size 2
- // Data for ADD (length 2)
- 0x1B, 0x3D,
- 0x3F, // VCD_COPY mode VCD_NEAR(0) size 15
- 0x84, // Address of copy: upper bits (525 + 2 = 527)
- 0x0F, // Address of copy: lower bits
- 0x02, // VCD_ADD size 1
- // Data for ADD (length 1)
- 0x1C,
- 0x4F, // VCD_COPY mode VCD_NEAR(1) size 15
- 0x10, // Address of copy
- 0x02, // VCD_ADD size 1
- // Data for ADD (length 1)
- 0x2C,
- 0x53, // VCD_COPY mode VCD_NEAR(2) size 0
- 0x87, // Size of copy: upper bits (256 * 4 - 51 = 973)
- 0x4D, // Size of copy: lower bits
- 0x10 // Address of copy
- };
-
-// This is similar to VCDiffInterleavedDecoderTest, but uses the custom code
-// table to eliminate the need to explicitly encode instruction sizes.
-// Notice that NEAR(0) mode is used here where NEAR(1) mode was used in
-// VCDiffInterleavedDecoderTest. This is because the custom code table
-// has the size of the NEAR cache set to 1; only the most recent
-// COPY instruction is available. This will also be a test of
-// custom cache sizes.
-const char VCDiffCustomCodeTableDecoderTest::kWindowHeader[] = {
- VCD_SOURCE, // Win_Indicator: take source from dictionary
- FirstByteOfStringLength(kDictionary), // Source segment size
- SecondByteOfStringLength(kDictionary),
- 0x00, // Source segment position: start of dictionary
- 0x74, // Length of the delta encoding
- FirstByteOfStringLength(kExpectedTarget), // Size of the target window
- SecondByteOfStringLength(kExpectedTarget),
- 0x00, // Delta_indicator (no compression)
- 0x00, // length of data for ADDs and RUNs (unused)
- 0x6E, // length of interleaved section
- 0x00 // length of addresses for COPYs (unused)
- };
-
-const char VCDiffCustomCodeTableDecoderTest::kWindowBody[] = {
- 0x22, // VCD_COPY mode VCD_SELF, size 28
- 0x00, // Address of COPY: Start of dictionary
- 0x12, // VCD_ADD size 61
- // Data for ADD (length 61)
- ' ', 'I', ' ', 'h', 'a', 'v', 'e', ' ', 's', 'a', 'i', 'd', ' ',
- 'i', 't', ' ', 't', 'w', 'i', 'c', 'e', ':', '\n',
- 'T', 'h', 'a', 't', ' ',
- 'a', 'l', 'o', 'n', 'e', ' ', 's', 'h', 'o', 'u', 'l', 'd', ' ',
- 'e', 'n', 'c', 'o', 'u', 'r', 'a', 'g', 'e', ' ',
- 't', 'h', 'e', ' ', 'c', 'r', 'e', 'w', '.', '\n',
- 0x32, // VCD_COPY mode VCD_HERE, size 44
- 0x58, // HERE mode address (27+61 back from here_address)
- 0xBF, // VCD_ADD size 2 + VCD_COPY mode NEAR(0), size 5
- // Data for ADDs: 2nd section (length 2)
- 'h', 'r',
- 0x2D, // NEAR(0) mode address (45 after prior address)
- 0x0A, // VCD_ADD size 9
- // Data for ADDs: 3rd section (length 9)
- 'W', 'h', 'a', 't', ' ',
- 'I', ' ', 't', 'e',
- 0x03, // VCD_RUN size 2
- // Data for RUN: 4th section (length 1)
- 'l',
- 0x11, // VCD_ADD size 27
- // Data for ADD: 4th section (length 27)
- ' ', 'y', 'o', 'u', ' ',
- 't', 'h', 'r', 'e', 'e', ' ', 't', 'i', 'm', 'e', 's', ' ', 'i', 's', ' ',
- 't', 'r', 'u', 'e', '.', '\"', '\n'
- };
-
-VCDiffCustomCodeTableDecoderTest::VCDiffCustomCodeTableDecoderTest() {
- delta_file_header_.assign(kFileHeader, sizeof(kFileHeader));
- delta_file_header_.push_back(0x01); // NEAR cache size (custom)
- delta_file_header_.push_back(0x06); // SAME cache size (custom)
- delta_file_header_.append(kEncodedCustomCodeTable,
- sizeof(kEncodedCustomCodeTable));
- delta_window_header_.assign(kWindowHeader, sizeof(kWindowHeader));
- delta_window_body_.assign(kWindowBody, sizeof(kWindowBody));
-}
-
-TEST_F(VCDiffCustomCodeTableDecoderTest, CustomCodeTableEncodingMatches) {
- VCDiffCodeTableData custom_code_table(
- VCDiffCodeTableData::kDefaultCodeTableData);
- custom_code_table.inst1[3] = VCD_RUN;
- custom_code_table.size1[17] = 27;
- custom_code_table.size1[18] = 61;
- custom_code_table.size1[34] = 28;
- custom_code_table.size1[50] = 44;
-
- decoder_.StartDecoding(
- reinterpret_cast<const char*>(
- &VCDiffCodeTableData::kDefaultCodeTableData),
- sizeof(VCDiffCodeTableData::kDefaultCodeTableData));
- EXPECT_TRUE(decoder_.DecodeChunk(kEncodedCustomCodeTable,
- sizeof(kEncodedCustomCodeTable),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(sizeof(custom_code_table), output_.size());
- const VCDiffCodeTableData* decoded_table =
- reinterpret_cast<const VCDiffCodeTableData*>(output_.data());
- EXPECT_EQ(VCD_RUN, decoded_table->inst1[0]);
- EXPECT_EQ(VCD_RUN, decoded_table->inst1[3]);
- EXPECT_EQ(27, decoded_table->size1[17]);
- EXPECT_EQ(61, decoded_table->size1[18]);
- EXPECT_EQ(28, decoded_table->size1[34]);
- EXPECT_EQ(44, decoded_table->size1[50]);
- for (int i = 0; i < VCDiffCodeTableData::kCodeTableSize; ++i) {
- EXPECT_EQ(custom_code_table.inst1[i], decoded_table->inst1[i]);
- EXPECT_EQ(custom_code_table.inst2[i], decoded_table->inst2[i]);
- EXPECT_EQ(custom_code_table.size1[i], decoded_table->size1[i]);
- EXPECT_EQ(custom_code_table.size2[i], decoded_table->size2[i]);
- EXPECT_EQ(custom_code_table.mode1[i], decoded_table->mode1[i]);
- EXPECT_EQ(custom_code_table.mode2[i], decoded_table->mode2[i]);
- }
-}
-
-TEST_F(VCDiffCustomCodeTableDecoderTest, DecodeUsingCustomCodeTable) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_));
- EXPECT_TRUE(decoder_.FinishDecoding());
- EXPECT_EQ(expected_target_, output_);
-}
-
-TEST_F(VCDiffCustomCodeTableDecoderTest, IncompleteCustomCodeTable) {
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
- delta_file_header_.size() - 1,
- &output_));
- EXPECT_FALSE(decoder_.FinishDecoding());
- EXPECT_EQ("", output_);
-}
-
-typedef VCDiffCustomCodeTableDecoderTest
- VCDiffCustomCodeTableDecoderTestByteByByte;
-
-TEST_F(VCDiffCustomCodeTableDecoderTestByteByByte, DecodeUsingCustomCodeTable) {
- 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(VCDiffCustomCodeTableDecoderTestByteByByte, IncompleteCustomCodeTable) {
- delta_file_.resize(delta_file_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_);
-}
-
-#ifdef GTEST_HAS_DEATH_TEST
-typedef VCDiffCustomCodeTableDecoderTest VCDiffCustomCodeTableDecoderDeathTest;
-
-TEST_F(VCDiffCustomCodeTableDecoderDeathTest, BadCustomCacheSizes) {
- delta_file_header_.assign(kFileHeader, sizeof(kFileHeader));
- delta_file_header_.push_back(0x81); // NEAR cache size (top bit)
- delta_file_header_.push_back(0x10); // NEAR cache size (custom value 0x90)
- delta_file_header_.push_back(0x81); // SAME cache size (top bit)
- delta_file_header_.push_back(0x10); // SAME cache size (custom value 0x90)
- delta_file_header_.append(kEncodedCustomCodeTable,
- sizeof(kEncodedCustomCodeTable));
- InitializeDeltaFile();
- decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
- EXPECT_DEBUG_DEATH(EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
- delta_file_.size(),
- &output_)),
- "cache");
- EXPECT_EQ("", output_);
-}
-#endif // GTEST_HAS_DEATH_TEST
-
-} // namespace open_vcdiff
-} // unnamed namespace

Powered by Google App Engine
This is Rietveld 408576698