1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Copyright 2008 Google Inc. 2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Author: Lincoln Smith 3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Licensed under the Apache License, Version 2.0 (the "License"); 5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// you may not use this file except in compliance with the License. 6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// You may obtain a copy of the License at 7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// http://www.apache.org/licenses/LICENSE-2.0 9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Unless required by applicable law or agreed to in writing, software 11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// distributed under the License is distributed on an "AS IS" BASIS, 12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// See the License for the specific language governing permissions and 14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limitations under the License. 15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <config.h> 17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "google/vcdecoder.h" 1828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <stdlib.h> // free, posix_memalign 1928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <string.h> // memcpy 20311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <string> 21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "testing.h" 22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "varint_bigendian.h" 23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "vcdecoder_test.h" 24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "vcdiff_defs.h" // VCD_SOURCE 25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_MALLOC_H 27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <malloc.h> 28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_MALLOC_H 29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_SYS_MMAN_H 31732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 32732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#undef _XOPEN_SOURCE 33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define _XOPEN_SOURCE 600 // posix_memalign 34732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#endif 35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <sys/mman.h> // mprotect 36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_SYS_MMAN_H 37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_UNISTD_H 39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <unistd.h> // getpagesize 40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_UNISTD_H 41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffnamespace open_vcdiff { 43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Test headers, valid and invalid. 45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 46311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, DecodeHeaderOnly) { 47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), 49311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_header_.size(), 50311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 51311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 52311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 53311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 54311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 55311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, PartialHeaderNotEnough) { 56311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 57311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(), 58311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_header_.size() - 2, 59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.FinishDecoding()); 61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, BadMagicNumber) { 65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[1] = 'Q' | 0x80; 66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, BadVersionNumber) { 74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[3] = 0x01; 75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, SecondaryCompressionNotSupported) { 83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[4] = 0x01; 84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, Decode) { 92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 97732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, DecodeWithChecksum) { 101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ComputeAndAddChecksum(); 102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 108732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, ChecksumDoesNotMatch) { 112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff AddChecksum(0xBADBAD); 113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, ChecksumIsInvalid64BitVarint) { 122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 0x80, 0x80, 0x80, 0x00 }; 124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_[0] |= VCD_CHECKSUM; 125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint)); 126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Adjust delta window size to include size of invalid Varint. 127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff string size_of_invalid_varint; 128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VarintBE<int32_t>::AppendToString( 129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)), 130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &size_of_invalid_varint); 131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_.replace(4, 1, size_of_invalid_varint); 132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Remove one byte from the length of the chunk to process, and 141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// verify that an error is returned for FinishDecoding(). 142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindow) { 143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size() - 1, 146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.FinishDecoding()); 148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindowHeader) { 153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_header_.size() 156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff + delta_window_header_.size() - 1, 157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.FinishDecoding()); 159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 16328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTest, TargetMatchesWindowSizeLimit) { 16428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetWindowSize(expected_target_.size()); 16528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 16628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 16728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff delta_file_.size(), 16828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff &output_)); 16928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 170732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 17128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 17228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 17328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTest, TargetMatchesFileSizeLimit) { 17428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetFileSize(expected_target_.size()); 17528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 17628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(), 17728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff delta_file_.size(), 17828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff &output_)); 17928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 180732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 18128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 18228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 18328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTest, TargetExceedsWindowSizeLimit) { 18428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1); 18528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 18628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 18728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff delta_file_.size(), 18828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff &output_)); 18928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_EQ("", output_); 19028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 19128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 19228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTest, TargetExceedsFileSizeLimit) { 19328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1); 19428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 19528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 19628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff delta_file_.size(), 19728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff &output_)); 19828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_EQ("", output_); 19928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 20028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 201311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Fuzz bits to make sure decoder does not violently crash. 202311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// This test has no expected behavior except that no crashes should occur. 203311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// In some cases, changing bits will still decode to the correct target; 204311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// for example, changing unused bits within a bitfield. 205311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, FuzzBits) { 206311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff while (FuzzOneByteInDeltaFile()) { 207311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 208311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (decoder_.DecodeChunk(delta_file_.data(), 209311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 210311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)) { 211311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.FinishDecoding(); 212311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 213311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 214311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff output_.clear(); 215311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 216311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 217311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 218311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// If a checksum is present, then fuzzing any of the bits may produce an error, 219311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// but it should not result in an incorrect target being produced without 220311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// an error. 221311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, FuzzBitsWithChecksum) { 222311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ComputeAndAddChecksum(); 223311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 224311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff while (FuzzOneByteInDeltaFile()) { 225311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 226311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (decoder_.DecodeChunk(delta_file_.data(), 227311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 228311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)) { 229311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (decoder_.FinishDecoding()) { 230311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Decoding succeeded. Make sure the correct target was produced. 231732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 232311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 233311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } else { 234311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 235311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 236311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 237311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff output_.clear(); 238311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 239311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 240311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 241311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopyMoreThanExpectedTarget) { 242311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0C] = 243311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 244311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0D] = 245311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 246311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 247311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 248311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 249311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 250311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 251311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 252311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 253311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeZero) { 254311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0C] = 0; 255311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 256311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 257311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 258311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 259311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 260311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 261311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 262311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeTooLargeByOne) { 263311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x0C]; 264311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 265311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 266311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 267311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 268311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 269311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 270311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 271311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeTooSmallByOne) { 272311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x0C]; 273311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 274311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 275311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 276311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 277311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 278311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 279311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 280311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeMaxInt) { 281311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0C, 1); 282311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 283311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 284311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 285311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 286311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 287311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 288311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 289311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeNegative) { 290311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0C, 1); 291311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 292311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 293311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 294311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 295311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 296311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 297311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 298311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopySizeInvalid) { 299311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0C, 1); 300311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 301311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 302311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 303311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 304311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 305311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 306311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 307311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopyAddressBeyondHereAddress) { 308311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0D] = 309311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kDictionary); 310311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0E] = 311311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kDictionary); 312311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 313311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 314311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 315311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 316311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 317311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 318311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 319311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopyAddressMaxInt) { 320311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0D, 1); 321311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 322311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 323311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 324311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 325311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 326311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 327311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 328311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopyAddressNegative) { 329311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0D, 1); 330311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 331311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 332311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 333311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 334311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 335311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 336311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 337311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, CopyAddressInvalid) { 338311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0D, 1); 339311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 340311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 341311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 342311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 343311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 344311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 345311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 346311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddMoreThanExpectedTarget) { 347311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0F] = 348311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 349311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x10] = 350311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 351311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 352311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 353311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 354311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 355311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 356311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 357311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 358311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeZero) { 359311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0F] = 0; 360311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 361311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 362311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 363311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 364311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 365311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 366311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 367311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeTooLargeByOne) { 368311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x0F]; 369311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 370311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 371311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 372311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 373311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 374311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 375311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 376311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeTooSmallByOne) { 377311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x0F]; 378311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 379311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 380311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 381311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 382311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 383311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 384311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 385311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeMaxInt) { 386311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0F, 1); 387311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 388311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 389311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 390311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 391311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 392311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 393311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 394311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeNegative) { 395311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0F, 1); 396311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 397311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 398311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 399311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 400311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 401311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 402311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 403311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, AddSizeInvalid) { 404311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0F, 1); 405311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 406311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 407311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 408311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 409311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 410311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 411311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 412311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunMoreThanExpectedTarget) { 413311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x5F] = 414311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 415311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x60] = 416311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 417311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 418311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 419311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 420311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 421311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 422311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 423311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 424311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeZero) { 425311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x5F] = 0; 426311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 427311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 428311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 429311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 430311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 431311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 432311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 433311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeTooLargeByOne) { 434311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x5F]; 435311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 436311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 437311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 438311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 439311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 440311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 441311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 442311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeTooSmallByOne) { 443311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x5F]; 444311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 445311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 446311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 447311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 448311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 449311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 450311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 451311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeMaxInt) { 452311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x5F, 1); 453311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 454311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 455311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 456311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 457311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 458311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 459311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 460311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeNegative) { 461311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x5F, 1); 462311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 463311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 464311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 465311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 466311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 467311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 468311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 469311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, RunSizeInvalid) { 470311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x5F, 1); 471311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 472311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(), 473311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 474311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 475311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 476311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 477311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 478311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#if defined(HAVE_MPROTECT) && \ 479311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff (defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN)) 480311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastEndOfBuffer) { 481311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Allocate two memory pages. 482311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const int page_size = getpagesize(); 483311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void* two_pages = NULL; 484311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_POSIX_MEMALIGN 485311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff posix_memalign(&two_pages, page_size, 2 * page_size); 486311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#else // !HAVE_POSIX_MEMALIGN 487311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff two_pages = memalign(page_size, 2 * page_size); 488311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_POSIX_MEMALIGN 489311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* const first_page = reinterpret_cast<char*>(two_pages); 490311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* const second_page = first_page + page_size; 491311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 492311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Place the delta string at the end of the first page. 493311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* delta_with_guard = second_page - delta_file_.size(); 494311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff memcpy(delta_with_guard, delta_file_.data(), delta_file_.size()); 495311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 496311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Make the second page unreadable. 497311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff mprotect(second_page, page_size, PROT_NONE); 498311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 499311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Now perform the decode operation, which will cause a segmentation fault 500311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // if it reads past the end of the buffer. 501311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 502311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard, 503311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 504311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 505311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 506732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 507311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 508311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Undo the mprotect. 509311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff mprotect(second_page, page_size, PROT_READ|PROT_WRITE); 510311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff free(two_pages); 511311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 512311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 513311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastBeginningOfBuffer) { 514311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Allocate two memory pages. 515311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const int page_size = getpagesize(); 516311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff void* two_pages = NULL; 517311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_POSIX_MEMALIGN 518311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff posix_memalign(&two_pages, page_size, 2 * page_size); 519311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#else // !HAVE_POSIX_MEMALIGN 520311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff two_pages = memalign(page_size, 2 * page_size); 521311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_POSIX_MEMALIGN 522311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* const first_page = reinterpret_cast<char*>(two_pages); 523311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* const second_page = first_page + page_size; 524311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 525311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Make the first page unreadable. 526311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff mprotect(first_page, page_size, PROT_NONE); 527311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 528311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Place the delta string at the beginning of the second page. 529311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff char* delta_with_guard = second_page; 530311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff memcpy(delta_with_guard, delta_file_.data(), delta_file_.size()); 531311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 532311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Now perform the decode operation, which will cause a segmentation fault 533311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // if it reads past the beginning of the buffer. 534311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 535311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard, 536311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.size(), 537311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &output_)); 538311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 539732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 540311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 541311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Undo the mprotect. 542311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff mprotect(first_page, page_size, PROT_READ|PROT_WRITE); 543311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff free(two_pages); 544311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 545311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_MPROTECT && (HAVE_MEMALIGN || HAVE_POSIX_MEMALIGN) 546311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 547311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// These are the same tests as for VCDiffInterleavedDecoderTest, with the added 548311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// complication that instead of calling DecodeChunk() once with the entire data 549311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// set, DecodeChunk() is called once for each byte of input. This is intended 550311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// to shake out any bugs with rewind and resume while parsing chunked data. 551311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 552311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdifftypedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte; 553311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 554311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Test headers, valid and invalid. 555311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 556311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeHeaderOnly) { 557311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 558311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_header_.size(); ++i) { 559311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_header_[i], 1, &output_)); 560311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 561311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 562311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 563311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 564311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 565311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, PartialHeaderNotEnough) { 566311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_.resize(delta_file_header_.size() - 2); 567311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 568311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 569311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 570311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 571311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_FALSE(decoder_.FinishDecoding()); 572311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 573311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 574311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 575311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, BadMagicNumber) { 576311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[1] = 'Q' | 0x80; 577311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 578311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 579311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 580311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 581311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 582311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(1U, i); 583311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 584311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 585311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 586311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 587311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 588311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 589311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 590311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 591311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, BadVersionNumber) { 592311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[3] = 0x01; 593311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 594311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 595311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 596311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 597311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 598311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 599311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(3U, i); 600311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 601311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 602311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 603311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 604311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 605311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 606311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 607311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, 608311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondaryCompressionNotSupported) { 609311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[4] = 0x01; 610311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 611311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 612311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 613311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 614311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 615311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 616311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(4U, i); 617311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 618311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 619311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 620311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 621311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 622311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 623311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 624311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, Decode) { 625311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 626311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 627311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 628311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 629311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 630732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 631311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 632311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 633311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeWithChecksum) { 634311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ComputeAndAddChecksum(); 635311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 636311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 637311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 638311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 639311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 640311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 641732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 642311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 643311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 644311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumDoesNotMatch) { 645311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff AddChecksum(0xBADBAD); 646311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 647311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 648311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 649311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 650311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 651311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 652311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail after decoding the entire delta file 653311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_.size() - 1, i); 654311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 655311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 656311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 657311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 658311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 659311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 660311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 661311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 662311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumIsInvalid64BitVarint) { 663311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 664311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 0x80, 0x80, 0x80, 0x00 }; 665311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_[0] |= VCD_CHECKSUM; 666311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint)); 667311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Adjust delta window size to include size of invalid Varint. 668311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff string size_of_invalid_varint; 669311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff VarintBE<int32_t>::AppendToString( 670311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)), 671311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff &size_of_invalid_varint); 672311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_.replace(4, 1, size_of_invalid_varint); 673311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 674311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 675311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 676311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 677311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 678311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 679311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail while trying to interpret the checksum. 680311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() - 2, i); 681311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 682311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 683311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 684311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 685311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 686311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 687311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 688311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 68928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesWindowSizeLimit) { 69028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetWindowSize(expected_target_.size()); 69128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 69228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 69328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 69428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 69528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 696732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 69728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 69828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 69928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesFileSizeLimit) { 70028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetFileSize(expected_target_.size()); 70128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 70228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 70328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_)); 70428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 70528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(decoder_.FinishDecoding()); 706732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 70728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 70828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 70928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsWindowSizeLimit) { 71028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1); 71128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 71228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff bool failed = false; 71328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 71428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 71528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff failed = true; 71628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff break; 71728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 71828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 71928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(failed); 72028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_EQ("", output_); 72128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 72228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 72328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsFileSizeLimit) { 72428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1); 72528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 72628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff bool failed = false; 72728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 72828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 72928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff failed = true; 73028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff break; 73128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 73228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff } 73328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_TRUE(failed); 73428db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff EXPECT_EQ("", output_); 73528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff} 73628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 737311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Fuzz bits to make sure decoder does not violently crash. 738311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// This test has no expected behavior except that no crashes should occur. 739311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// In some cases, changing bits will still decode to the correct target; 740311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// for example, changing unused bits within a bitfield. 741311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBits) { 742311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff while (FuzzOneByteInDeltaFile()) { 743311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 744311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 745311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 746311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 747311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 748311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 749311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 750311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 751311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!failed) { 752311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.FinishDecoding(); 753311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 754311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 755311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff output_.clear(); 756311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 757311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 758311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 759311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// If a checksum is present, then fuzzing any of the bits may produce an error, 760311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// but it should not result in an incorrect target being produced without 761311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// an error. 762311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBitsWithChecksum) { 763311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ComputeAndAddChecksum(); 764311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 765311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff while (FuzzOneByteInDeltaFile()) { 766311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 767311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 768311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 769311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 770311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 771311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 772311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 773311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 774311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!failed) { 775311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (decoder_.FinishDecoding()) { 776311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Decoding succeeded. Make sure the correct target was produced. 777732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com EXPECT_EQ(expected_target_.c_str(), output_); 778311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 779311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 780311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 781311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 782311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 783311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff output_.clear(); 784311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 785311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 786311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 787311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, 788311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff CopyInstructionsShouldFailIfNoSourceSegment) { 789311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Replace the Win_Indicator and the source size and source offset with a 790311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // single 0 byte (a Win_Indicator for a window with no source segment.) 791311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_window_header_.replace(0, 4, "\0", 1); 792311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff InitializeDeltaFile(); 793311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 794311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 795311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 796311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 797311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 798311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The first COPY instruction should fail. 799311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() + 2, i); 800311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 801311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 802311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 803311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 804311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ("", output_); 805311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 806311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 807311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyMoreThanExpectedTarget) { 808311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0C] = 809311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 810311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0D] = 811311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 812311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 813311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 814311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 815311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 816311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 817311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 818311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x0D, i); 819311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 820311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 821311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 822311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 823311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 824311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 825311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 826311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 827311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// A COPY instruction with an explicit size of 0 is not illegal according to the 828311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// standard, although it is inefficient and should not be generated by any 829311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// reasonable encoder. Changing the size of a COPY instruction to zero will 830311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// cause a failure because the generated target window size will not match the 831311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// expected target size. 832311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeZero) { 833311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0C] = 0; 834311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 835311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 836311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 837311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 838311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 839311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 840311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 841311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 842311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 843311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 844311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 845311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 846311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 847311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooLargeByOne) { 848311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x0C]; 849311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 850311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 851311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 852311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 853311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 854311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 855311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 856311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 857311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 858311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 859311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 860311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 861311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 862311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooSmallByOne) { 863311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x0C]; 864311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 865311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 866311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 867311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 868311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 869311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 870311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 871311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 872311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 873311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 874311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 875311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 876311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 877311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeMaxInt) { 878311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0C, 1); 879311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 880311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 881311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 882311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 883311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 884311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 885311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x10, i); 886311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 887311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 888311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 889311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 890311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 891311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 892311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 893311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 894311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeNegative) { 895311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0C, 1); 896311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 897311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 898311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 899311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 900311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 901311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 902f1dd933c4e47a65889b4bba2a5f58b12aac53383openvcdiff@gmail.com EXPECT_EQ(delta_file_header_.size() + 0x0F, i); 903311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 904311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 905311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 906311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 907311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 908311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 909311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 910311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 911311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeInvalid) { 912311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0C, 1); 913311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 914311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 915311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 916311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 917311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 918311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 919311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x10, i); 920311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 921311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 922311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 923311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 924311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 925311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 926311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 927311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 928311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressBeyondHereAddress) { 929311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0D] = 930311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kDictionary); 931311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0E] = 932311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kDictionary); 933311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 934311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 935311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 936311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 937311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 938311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 939311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x0E, i); 940311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 941311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 942311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 943311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 944311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 945311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 946311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 947311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 948311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressMaxInt) { 949311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0D, 1); 950311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 951311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 952311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 953311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 954311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 955311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 956311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x11, i); 957311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 958311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 959311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 960311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 961311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 962311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 963311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 964311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 965311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressNegative) { 966311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0D, 1); 967311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 968311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 969311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 970311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 971311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 972311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 973f1dd933c4e47a65889b4bba2a5f58b12aac53383openvcdiff@gmail.com EXPECT_EQ(delta_file_header_.size() + 0x10, i); 974311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 975311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 976311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 977311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 978311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 979311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 980311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 981311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 982311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressInvalid) { 983311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0D, 1); 984311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 985311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 986311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 987311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 988311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 989311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 990311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x11, i); 991311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 992311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 993311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 994311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 995311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 996311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 997311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 998311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 999311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddMoreThanExpectedTarget) { 1000311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0F] = 1001311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 1002311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x10] = 1003311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 1004311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1005311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1006311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1007311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1008311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1009311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1010311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x10, i); 1011311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1012311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1013311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1014311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1015311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1016311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1017311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1018311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1019311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// An ADD instruction with an explicit size of 0 is not illegal according to the 1020311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// standard, although it is inefficient and should not be generated by any 1021311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// reasonable encoder. Changing the size of an ADD instruction to zero will 1022311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// cause a failure because the generated target window size will not match the 1023311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// expected target size. 1024311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeZero) { 1025311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x0F] = 0; 1026311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1027311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1028311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1029311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1030311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1031311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1032311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1033311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1034311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1035311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1036311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1037311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1038311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1039311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooLargeByOne) { 1040311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x0F]; 1041311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1042311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1043311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1044311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1045311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1046311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1047311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1048311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1049311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1050311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1051311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1052311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1053311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1054311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooSmallByOne) { 1055311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x0F]; 1056311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1057311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1058311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1059311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1060311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1061311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1062311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1063311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1064311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1065311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1066311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1067311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1068311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1069311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeMaxInt) { 1070311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x0F, 1); 1071311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1072311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1073311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1074311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1075311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1076311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1077311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x13, i); 1078311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1079311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1080311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1081311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1082311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1083311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1084311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1085311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1086311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeNegative) { 1087311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x0F, 1); 1088311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1089311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1090311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1091311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1092311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1093311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1094f1dd933c4e47a65889b4bba2a5f58b12aac53383openvcdiff@gmail.com EXPECT_EQ(delta_file_header_.size() + 0x12, i); 1095311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1096311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1097311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1098311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1099311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeInvalid) { 1104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x0F, 1); 1105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1108311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x13, i); 1112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunMoreThanExpectedTarget) { 1121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x5F] = 1122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff FirstByteOfStringLength(kExpectedTarget); 1123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x60] = 1124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff SecondByteOfStringLength(kExpectedTarget) + 1; 1125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x60, i); 1132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// A RUN instruction with an explicit size of 0 is not illegal according to the 1141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// standard, although it is inefficient and should not be generated by any 1142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// reasonable encoder. Changing the size of a RUN instruction to zero will 1143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// cause a failure because the generated target window size will not match the 1144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// expected target size. 1145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeZero) { 1146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff delta_file_[delta_file_header_.size() + 0x5F] = 0; 1147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooLargeByOne) { 1161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff ++delta_file_[delta_file_header_.size() + 0x5F]; 1162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1163311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1164311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1165311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1166311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1167311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1168311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1169311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1170311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1171311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1172311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1173311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1174311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1175311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooSmallByOne) { 1176311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff --delta_file_[delta_file_header_.size() + 0x5F]; 1177311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1178311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1179311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1180311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1181311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1182311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1183311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1184311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1185311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1186311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1187311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1188311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1189311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1190311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeMaxInt) { 1191311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteMaxVarintAtOffset(0x5F, 1); 1192311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1193311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1194311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1195311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1196311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1197311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1198311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x63, i); 1199311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1200311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1201311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1202311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1203311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1204311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1205311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1206311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1207311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeNegative) { 1208311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteNegativeVarintAtOffset(0x5F, 1); 1209311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1210311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1211311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1212311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1213311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1214311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1215f1dd933c4e47a65889b4bba2a5f58b12aac53383openvcdiff@gmail.com EXPECT_EQ(delta_file_header_.size() + 0x62, i); 1216311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1217311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1218311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1219311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1220311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1221311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1222311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1223311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1224311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffTEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeInvalid) { 1225311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff WriteInvalidVarintAtOffset(0x5F, 1); 1226311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff decoder_.StartDecoding(dictionary_.data(), dictionary_.size()); 1227311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff bool failed = false; 1228311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff for (size_t i = 0; i < delta_file_.size(); ++i) { 1229311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { 1230311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff failed = true; 1231311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // It should fail at the position that was altered 1232311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_EQ(delta_file_header_.size() + 0x63, i); 1233311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff break; 1234311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1235311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 1236311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_TRUE(failed); 1237311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // The decoder should not create more target bytes than were expected. 1238311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff EXPECT_GE(expected_target_.size(), output_.size()); 1239311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 1240311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 1241311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} // namespace open_vcdiff 1242