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 |