• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 Google Inc.
2 // Author: Lincoln Smith
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include <config.h>
17 #include "google/vcdecoder.h"
18 #include <stdlib.h>  // free, posix_memalign
19 #include <string.h>  // memcpy
20 #include <string>
21 #include "testing.h"
22 #include "varint_bigendian.h"
23 #include "vcdecoder_test.h"
24 #include "vcdiff_defs.h"  // VCD_SOURCE
25 
26 #ifdef HAVE_MALLOC_H
27 #include <malloc.h>
28 #endif  // HAVE_MALLOC_H
29 
30 #ifdef HAVE_SYS_MMAN_H
31 #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600
32 #undef  _XOPEN_SOURCE
33 #define _XOPEN_SOURCE 600  // posix_memalign
34 #endif
35 #include <sys/mman.h>  // mprotect
36 #endif  // HAVE_SYS_MMAN_H
37 
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>  // getpagesize
40 #endif  // HAVE_UNISTD_H
41 
42 namespace open_vcdiff {
43 
44 // Test headers, valid and invalid.
45 
TEST_F(VCDiffInterleavedDecoderTest,DecodeHeaderOnly)46 TEST_F(VCDiffInterleavedDecoderTest, DecodeHeaderOnly) {
47   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
48   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
49                                    delta_file_header_.size(),
50                                    &output_));
51   EXPECT_TRUE(decoder_.FinishDecoding());
52   EXPECT_EQ("", output_);
53 }
54 
TEST_F(VCDiffInterleavedDecoderTest,PartialHeaderNotEnough)55 TEST_F(VCDiffInterleavedDecoderTest, PartialHeaderNotEnough) {
56   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
57   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
58                                    delta_file_header_.size() - 2,
59                                    &output_));
60   EXPECT_FALSE(decoder_.FinishDecoding());
61   EXPECT_EQ("", output_);
62 }
63 
TEST_F(VCDiffInterleavedDecoderTest,BadMagicNumber)64 TEST_F(VCDiffInterleavedDecoderTest, BadMagicNumber) {
65   delta_file_[1] = 'Q' | 0x80;
66   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
67   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
68                                     delta_file_.size(),
69                                     &output_));
70   EXPECT_EQ("", output_);
71 }
72 
TEST_F(VCDiffInterleavedDecoderTest,BadVersionNumber)73 TEST_F(VCDiffInterleavedDecoderTest, BadVersionNumber) {
74   delta_file_[3] = 0x01;
75   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
76   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
77                                     delta_file_.size(),
78                                     &output_));
79   EXPECT_EQ("", output_);
80 }
81 
TEST_F(VCDiffInterleavedDecoderTest,SecondaryCompressionNotSupported)82 TEST_F(VCDiffInterleavedDecoderTest, SecondaryCompressionNotSupported) {
83   delta_file_[4] = 0x01;
84   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
85   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
86                                     delta_file_.size(),
87                                     &output_));
88   EXPECT_EQ("", output_);
89 }
90 
TEST_F(VCDiffInterleavedDecoderTest,Decode)91 TEST_F(VCDiffInterleavedDecoderTest, Decode) {
92   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
93   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
94                                    delta_file_.size(),
95                                    &output_));
96   EXPECT_TRUE(decoder_.FinishDecoding());
97   EXPECT_EQ(expected_target_.c_str(), output_);
98 }
99 
TEST_F(VCDiffInterleavedDecoderTest,DecodeWithChecksum)100 TEST_F(VCDiffInterleavedDecoderTest, DecodeWithChecksum) {
101   ComputeAndAddChecksum();
102   InitializeDeltaFile();
103   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
104   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
105                                    delta_file_.size(),
106                                    &output_));
107   EXPECT_TRUE(decoder_.FinishDecoding());
108   EXPECT_EQ(expected_target_.c_str(), output_);
109 }
110 
TEST_F(VCDiffInterleavedDecoderTest,ChecksumDoesNotMatch)111 TEST_F(VCDiffInterleavedDecoderTest, ChecksumDoesNotMatch) {
112   AddChecksum(0xBADBAD);
113   InitializeDeltaFile();
114   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
115   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
116                                     delta_file_.size(),
117                                     &output_));
118   EXPECT_EQ("", output_);
119 }
120 
TEST_F(VCDiffInterleavedDecoderTest,ChecksumIsInvalid64BitVarint)121 TEST_F(VCDiffInterleavedDecoderTest, ChecksumIsInvalid64BitVarint) {
122   static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80,
123                                          0x80, 0x80, 0x80, 0x00 };
124   delta_window_header_[0] |= VCD_CHECKSUM;
125   delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint));
126   // Adjust delta window size to include size of invalid Varint.
127   string size_of_invalid_varint;
128   VarintBE<int32_t>::AppendToString(
129       static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)),
130       &size_of_invalid_varint);
131   delta_window_header_.replace(4, 1, size_of_invalid_varint);
132   InitializeDeltaFile();
133   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
134   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
135                                     delta_file_.size(),
136                                     &output_));
137   EXPECT_EQ("", output_);
138 }
139 
140 // Remove one byte from the length of the chunk to process, and
141 // verify that an error is returned for FinishDecoding().
TEST_F(VCDiffInterleavedDecoderTest,FinishAfterDecodingPartialWindow)142 TEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindow) {
143   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
144   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
145                                    delta_file_.size() - 1,
146                                    &output_));
147   EXPECT_FALSE(decoder_.FinishDecoding());
148   // The decoder should not create more target bytes than were expected.
149   EXPECT_GE(expected_target_.size(), output_.size());
150 }
151 
TEST_F(VCDiffInterleavedDecoderTest,FinishAfterDecodingPartialWindowHeader)152 TEST_F(VCDiffInterleavedDecoderTest, FinishAfterDecodingPartialWindowHeader) {
153   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
154   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
155                                    delta_file_header_.size()
156                                        + delta_window_header_.size() - 1,
157                                    &output_));
158   EXPECT_FALSE(decoder_.FinishDecoding());
159   // The decoder should not create more target bytes than were expected.
160   EXPECT_GE(expected_target_.size(), output_.size());
161 }
162 
TEST_F(VCDiffInterleavedDecoderTest,TargetMatchesWindowSizeLimit)163 TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesWindowSizeLimit) {
164   decoder_.SetMaximumTargetWindowSize(expected_target_.size());
165   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
166   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
167                                    delta_file_.size(),
168                                    &output_));
169   EXPECT_TRUE(decoder_.FinishDecoding());
170   EXPECT_EQ(expected_target_.c_str(), output_);
171 }
172 
TEST_F(VCDiffInterleavedDecoderTest,TargetMatchesFileSizeLimit)173 TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesFileSizeLimit) {
174   decoder_.SetMaximumTargetFileSize(expected_target_.size());
175   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
176   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
177                                    delta_file_.size(),
178                                    &output_));
179   EXPECT_TRUE(decoder_.FinishDecoding());
180   EXPECT_EQ(expected_target_.c_str(), output_);
181 }
182 
TEST_F(VCDiffInterleavedDecoderTest,TargetExceedsWindowSizeLimit)183 TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsWindowSizeLimit) {
184   decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
185   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
186   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
187                                     delta_file_.size(),
188                                     &output_));
189   EXPECT_EQ("", output_);
190 }
191 
TEST_F(VCDiffInterleavedDecoderTest,TargetExceedsFileSizeLimit)192 TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsFileSizeLimit) {
193   decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
194   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
195   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
196                                     delta_file_.size(),
197                                     &output_));
198   EXPECT_EQ("", output_);
199 }
200 
201 // Fuzz bits to make sure decoder does not violently crash.
202 // This test has no expected behavior except that no crashes should occur.
203 // In some cases, changing bits will still decode to the correct target;
204 // for example, changing unused bits within a bitfield.
TEST_F(VCDiffInterleavedDecoderTest,FuzzBits)205 TEST_F(VCDiffInterleavedDecoderTest, FuzzBits) {
206   while (FuzzOneByteInDeltaFile()) {
207     decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
208     if (decoder_.DecodeChunk(delta_file_.data(),
209                              delta_file_.size(),
210                              &output_)) {
211       decoder_.FinishDecoding();
212     }
213     InitializeDeltaFile();
214     output_.clear();
215   }
216 }
217 
218 // If a checksum is present, then fuzzing any of the bits may produce an error,
219 // but it should not result in an incorrect target being produced without
220 // an error.
TEST_F(VCDiffInterleavedDecoderTest,FuzzBitsWithChecksum)221 TEST_F(VCDiffInterleavedDecoderTest, FuzzBitsWithChecksum) {
222   ComputeAndAddChecksum();
223   InitializeDeltaFile();
224   while (FuzzOneByteInDeltaFile()) {
225     decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
226     if (decoder_.DecodeChunk(delta_file_.data(),
227                              delta_file_.size(),
228                              &output_)) {
229       if (decoder_.FinishDecoding()) {
230         // Decoding succeeded.  Make sure the correct target was produced.
231         EXPECT_EQ(expected_target_.c_str(), output_);
232       }
233     } else {
234       EXPECT_EQ("", output_);
235     }
236     InitializeDeltaFile();
237     output_.clear();
238   }
239 }
240 
TEST_F(VCDiffInterleavedDecoderTest,CopyMoreThanExpectedTarget)241 TEST_F(VCDiffInterleavedDecoderTest, CopyMoreThanExpectedTarget) {
242   delta_file_[delta_file_header_.size() + 0x0C] =
243       FirstByteOfStringLength(kExpectedTarget);
244   delta_file_[delta_file_header_.size() + 0x0D] =
245       SecondByteOfStringLength(kExpectedTarget) + 1;
246   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
247   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
248                                     delta_file_.size(),
249                                     &output_));
250   EXPECT_EQ("", output_);
251 }
252 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeZero)253 TEST_F(VCDiffInterleavedDecoderTest, CopySizeZero) {
254   delta_file_[delta_file_header_.size() + 0x0C] = 0;
255   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
256   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
257                                     delta_file_.size(),
258                                     &output_));
259   EXPECT_EQ("", output_);
260 }
261 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeTooLargeByOne)262 TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooLargeByOne) {
263   ++delta_file_[delta_file_header_.size() + 0x0C];
264   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
265   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
266                                     delta_file_.size(),
267                                     &output_));
268   EXPECT_EQ("", output_);
269 }
270 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeTooSmallByOne)271 TEST_F(VCDiffInterleavedDecoderTest, CopySizeTooSmallByOne) {
272   --delta_file_[delta_file_header_.size() + 0x0C];
273   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
274   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
275                                     delta_file_.size(),
276                                     &output_));
277   EXPECT_EQ("", output_);
278 }
279 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeMaxInt)280 TEST_F(VCDiffInterleavedDecoderTest, CopySizeMaxInt) {
281   WriteMaxVarintAtOffset(0x0C, 1);
282   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
283   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
284                                     delta_file_.size(),
285                                     &output_));
286   EXPECT_EQ("", output_);
287 }
288 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeNegative)289 TEST_F(VCDiffInterleavedDecoderTest, CopySizeNegative) {
290   WriteNegativeVarintAtOffset(0x0C, 1);
291   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
292   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
293                                     delta_file_.size(),
294                                     &output_));
295   EXPECT_EQ("", output_);
296 }
297 
TEST_F(VCDiffInterleavedDecoderTest,CopySizeInvalid)298 TEST_F(VCDiffInterleavedDecoderTest, CopySizeInvalid) {
299   WriteInvalidVarintAtOffset(0x0C, 1);
300   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
301   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
302                                     delta_file_.size(),
303                                     &output_));
304   EXPECT_EQ("", output_);
305 }
306 
TEST_F(VCDiffInterleavedDecoderTest,CopyAddressBeyondHereAddress)307 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressBeyondHereAddress) {
308   delta_file_[delta_file_header_.size() + 0x0D] =
309       FirstByteOfStringLength(kDictionary);
310   delta_file_[delta_file_header_.size() + 0x0E] =
311       SecondByteOfStringLength(kDictionary);
312   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
313   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
314                                     delta_file_.size(),
315                                     &output_));
316   EXPECT_EQ("", output_);
317 }
318 
TEST_F(VCDiffInterleavedDecoderTest,CopyAddressMaxInt)319 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressMaxInt) {
320   WriteMaxVarintAtOffset(0x0D, 1);
321   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
322   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
323                                     delta_file_.size(),
324                                     &output_));
325   EXPECT_EQ("", output_);
326 }
327 
TEST_F(VCDiffInterleavedDecoderTest,CopyAddressNegative)328 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressNegative) {
329   WriteNegativeVarintAtOffset(0x0D, 1);
330   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
331   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
332                                     delta_file_.size(),
333                                     &output_));
334   EXPECT_EQ("", output_);
335 }
336 
TEST_F(VCDiffInterleavedDecoderTest,CopyAddressInvalid)337 TEST_F(VCDiffInterleavedDecoderTest, CopyAddressInvalid) {
338   WriteInvalidVarintAtOffset(0x0D, 1);
339   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
340   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
341                                     delta_file_.size(),
342                                     &output_));
343   EXPECT_EQ("", output_);
344 }
345 
TEST_F(VCDiffInterleavedDecoderTest,AddMoreThanExpectedTarget)346 TEST_F(VCDiffInterleavedDecoderTest, AddMoreThanExpectedTarget) {
347   delta_file_[delta_file_header_.size() + 0x0F] =
348       FirstByteOfStringLength(kExpectedTarget);
349   delta_file_[delta_file_header_.size() + 0x10] =
350       SecondByteOfStringLength(kExpectedTarget) + 1;
351   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
352   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
353                                     delta_file_.size(),
354                                     &output_));
355   EXPECT_EQ("", output_);
356 }
357 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeZero)358 TEST_F(VCDiffInterleavedDecoderTest, AddSizeZero) {
359   delta_file_[delta_file_header_.size() + 0x0F] = 0;
360   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
361   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
362                                     delta_file_.size(),
363                                     &output_));
364   EXPECT_EQ("", output_);
365 }
366 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeTooLargeByOne)367 TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooLargeByOne) {
368   ++delta_file_[delta_file_header_.size() + 0x0F];
369   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
370   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
371                                     delta_file_.size(),
372                                     &output_));
373   EXPECT_EQ("", output_);
374 }
375 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeTooSmallByOne)376 TEST_F(VCDiffInterleavedDecoderTest, AddSizeTooSmallByOne) {
377   --delta_file_[delta_file_header_.size() + 0x0F];
378   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
379   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
380                                     delta_file_.size(),
381                                     &output_));
382   EXPECT_EQ("", output_);
383 }
384 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeMaxInt)385 TEST_F(VCDiffInterleavedDecoderTest, AddSizeMaxInt) {
386   WriteMaxVarintAtOffset(0x0F, 1);
387   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
388   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
389                                     delta_file_.size(),
390                                     &output_));
391   EXPECT_EQ("", output_);
392 }
393 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeNegative)394 TEST_F(VCDiffInterleavedDecoderTest, AddSizeNegative) {
395   WriteNegativeVarintAtOffset(0x0F, 1);
396   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
397   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
398                                     delta_file_.size(),
399                                     &output_));
400   EXPECT_EQ("", output_);
401 }
402 
TEST_F(VCDiffInterleavedDecoderTest,AddSizeInvalid)403 TEST_F(VCDiffInterleavedDecoderTest, AddSizeInvalid) {
404   WriteInvalidVarintAtOffset(0x0F, 1);
405   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
406   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
407                                     delta_file_.size(),
408                                     &output_));
409   EXPECT_EQ("", output_);
410 }
411 
TEST_F(VCDiffInterleavedDecoderTest,RunMoreThanExpectedTarget)412 TEST_F(VCDiffInterleavedDecoderTest, RunMoreThanExpectedTarget) {
413   delta_file_[delta_file_header_.size() + 0x5F] =
414       FirstByteOfStringLength(kExpectedTarget);
415   delta_file_[delta_file_header_.size() + 0x60] =
416       SecondByteOfStringLength(kExpectedTarget) + 1;
417   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
418   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
419                                     delta_file_.size(),
420                                     &output_));
421   EXPECT_EQ("", output_);
422 }
423 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeZero)424 TEST_F(VCDiffInterleavedDecoderTest, RunSizeZero) {
425   delta_file_[delta_file_header_.size() + 0x5F] = 0;
426   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
427   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
428                                     delta_file_.size(),
429                                     &output_));
430   EXPECT_EQ("", output_);
431 }
432 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeTooLargeByOne)433 TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooLargeByOne) {
434   ++delta_file_[delta_file_header_.size() + 0x5F];
435   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
436   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
437                                     delta_file_.size(),
438                                     &output_));
439   EXPECT_EQ("", output_);
440 }
441 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeTooSmallByOne)442 TEST_F(VCDiffInterleavedDecoderTest, RunSizeTooSmallByOne) {
443   --delta_file_[delta_file_header_.size() + 0x5F];
444   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
445   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
446                                     delta_file_.size(),
447                                     &output_));
448   EXPECT_EQ("", output_);
449 }
450 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeMaxInt)451 TEST_F(VCDiffInterleavedDecoderTest, RunSizeMaxInt) {
452   WriteMaxVarintAtOffset(0x5F, 1);
453   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
454   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
455                                     delta_file_.size(),
456                                     &output_));
457   EXPECT_EQ("", output_);
458 }
459 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeNegative)460 TEST_F(VCDiffInterleavedDecoderTest, RunSizeNegative) {
461   WriteNegativeVarintAtOffset(0x5F, 1);
462   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
463   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
464                                     delta_file_.size(),
465                                     &output_));
466   EXPECT_EQ("", output_);
467 }
468 
TEST_F(VCDiffInterleavedDecoderTest,RunSizeInvalid)469 TEST_F(VCDiffInterleavedDecoderTest, RunSizeInvalid) {
470   WriteInvalidVarintAtOffset(0x5F, 1);
471   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
472   EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
473                                     delta_file_.size(),
474                                     &output_));
475   EXPECT_EQ("", output_);
476 }
477 
478 #if defined(HAVE_MPROTECT) && \
479    (defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN))
TEST_F(VCDiffInterleavedDecoderTest,ShouldNotReadPastEndOfBuffer)480 TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastEndOfBuffer) {
481   // Allocate two memory pages.
482   const int page_size = getpagesize();
483   void* two_pages = NULL;
484 #ifdef HAVE_POSIX_MEMALIGN
485   posix_memalign(&two_pages, page_size, 2 * page_size);
486 #else  // !HAVE_POSIX_MEMALIGN
487   two_pages = memalign(page_size, 2 * page_size);
488 #endif  // HAVE_POSIX_MEMALIGN
489   char* const first_page = reinterpret_cast<char*>(two_pages);
490   char* const second_page = first_page + page_size;
491 
492   // Place the delta string at the end of the first page.
493   char* delta_with_guard = second_page - delta_file_.size();
494   memcpy(delta_with_guard, delta_file_.data(), delta_file_.size());
495 
496   // Make the second page unreadable.
497   mprotect(second_page, page_size, PROT_NONE);
498 
499   // Now perform the decode operation, which will cause a segmentation fault
500   // if it reads past the end of the buffer.
501   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
502   EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard,
503                                    delta_file_.size(),
504                                    &output_));
505   EXPECT_TRUE(decoder_.FinishDecoding());
506   EXPECT_EQ(expected_target_.c_str(), output_);
507 
508   // Undo the mprotect.
509   mprotect(second_page, page_size, PROT_READ|PROT_WRITE);
510   free(two_pages);
511 }
512 
TEST_F(VCDiffInterleavedDecoderTest,ShouldNotReadPastBeginningOfBuffer)513 TEST_F(VCDiffInterleavedDecoderTest, ShouldNotReadPastBeginningOfBuffer) {
514   // Allocate two memory pages.
515   const int page_size = getpagesize();
516   void* two_pages = NULL;
517 #ifdef HAVE_POSIX_MEMALIGN
518   posix_memalign(&two_pages, page_size, 2 * page_size);
519 #else  // !HAVE_POSIX_MEMALIGN
520   two_pages = memalign(page_size, 2 * page_size);
521 #endif  // HAVE_POSIX_MEMALIGN
522   char* const first_page = reinterpret_cast<char*>(two_pages);
523   char* const second_page = first_page + page_size;
524 
525   // Make the first page unreadable.
526   mprotect(first_page, page_size, PROT_NONE);
527 
528   // Place the delta string at the beginning of the second page.
529   char* delta_with_guard = second_page;
530   memcpy(delta_with_guard, delta_file_.data(), delta_file_.size());
531 
532   // Now perform the decode operation, which will cause a segmentation fault
533   // if it reads past the beginning of the buffer.
534   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
535   EXPECT_TRUE(decoder_.DecodeChunk(delta_with_guard,
536                                    delta_file_.size(),
537                                    &output_));
538   EXPECT_TRUE(decoder_.FinishDecoding());
539   EXPECT_EQ(expected_target_.c_str(), output_);
540 
541   // Undo the mprotect.
542   mprotect(first_page, page_size, PROT_READ|PROT_WRITE);
543   free(two_pages);
544 }
545 #endif  // HAVE_MPROTECT && (HAVE_MEMALIGN || HAVE_POSIX_MEMALIGN)
546 
547 // These are the same tests as for VCDiffInterleavedDecoderTest, with the added
548 // complication that instead of calling DecodeChunk() once with the entire data
549 // set, DecodeChunk() is called once for each byte of input.  This is intended
550 // to shake out any bugs with rewind and resume while parsing chunked data.
551 
552 typedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte;
553 
554 // Test headers, valid and invalid.
555 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,DecodeHeaderOnly)556 TEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeHeaderOnly) {
557   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
558   for (size_t i = 0; i < delta_file_header_.size(); ++i) {
559     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_header_[i], 1, &output_));
560   }
561   EXPECT_TRUE(decoder_.FinishDecoding());
562   EXPECT_EQ("", output_);
563 }
564 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,PartialHeaderNotEnough)565 TEST_F(VCDiffInterleavedDecoderTestByteByByte, PartialHeaderNotEnough) {
566   delta_file_.resize(delta_file_header_.size() - 2);
567   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
568   for (size_t i = 0; i < delta_file_.size(); ++i) {
569     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
570   }
571   EXPECT_FALSE(decoder_.FinishDecoding());
572   EXPECT_EQ("", output_);
573 }
574 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,BadMagicNumber)575 TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadMagicNumber) {
576   delta_file_[1] = 'Q' | 0x80;
577   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
578   bool failed = false;
579   for (size_t i = 0; i < delta_file_.size(); ++i) {
580     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
581       // It should fail at the position that was altered
582       EXPECT_EQ(1U, i);
583       failed = true;
584       break;
585     }
586   }
587   EXPECT_TRUE(failed);
588   EXPECT_EQ("", output_);
589 }
590 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,BadVersionNumber)591 TEST_F(VCDiffInterleavedDecoderTestByteByByte, BadVersionNumber) {
592   delta_file_[3] = 0x01;
593   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
594   bool failed = false;
595   for (size_t i = 0; i < delta_file_.size(); ++i) {
596     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
597       failed = true;
598       // It should fail at the position that was altered
599       EXPECT_EQ(3U, i);
600       break;
601     }
602   }
603   EXPECT_TRUE(failed);
604   EXPECT_EQ("", output_);
605 }
606 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,SecondaryCompressionNotSupported)607 TEST_F(VCDiffInterleavedDecoderTestByteByByte,
608        SecondaryCompressionNotSupported) {
609   delta_file_[4] = 0x01;
610   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
611   bool failed = false;
612   for (size_t i = 0; i < delta_file_.size(); ++i) {
613     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
614       failed = true;
615       // It should fail at the position that was altered
616       EXPECT_EQ(4U, i);
617       break;
618     }
619   }
620   EXPECT_TRUE(failed);
621   EXPECT_EQ("", output_);
622 }
623 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,Decode)624 TEST_F(VCDiffInterleavedDecoderTestByteByByte, Decode) {
625   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
626   for (size_t i = 0; i < delta_file_.size(); ++i) {
627     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
628   }
629   EXPECT_TRUE(decoder_.FinishDecoding());
630   EXPECT_EQ(expected_target_.c_str(), output_);
631 }
632 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,DecodeWithChecksum)633 TEST_F(VCDiffInterleavedDecoderTestByteByByte, DecodeWithChecksum) {
634   ComputeAndAddChecksum();
635   InitializeDeltaFile();
636   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
637   for (size_t i = 0; i < delta_file_.size(); ++i) {
638     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
639   }
640   EXPECT_TRUE(decoder_.FinishDecoding());
641   EXPECT_EQ(expected_target_.c_str(), output_);
642 }
643 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,ChecksumDoesNotMatch)644 TEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumDoesNotMatch) {
645   AddChecksum(0xBADBAD);
646   InitializeDeltaFile();
647   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
648   bool failed = false;
649   for (size_t i = 0; i < delta_file_.size(); ++i) {
650     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
651       failed = true;
652       // It should fail after decoding the entire delta file
653       EXPECT_EQ(delta_file_.size() - 1, i);
654       break;
655     }
656   }
657   EXPECT_TRUE(failed);
658   // The decoder should not create more target bytes than were expected.
659   EXPECT_GE(expected_target_.size(), output_.size());
660 }
661 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,ChecksumIsInvalid64BitVarint)662 TEST_F(VCDiffInterleavedDecoderTestByteByByte, ChecksumIsInvalid64BitVarint) {
663   static const char kInvalidVarint[] = { 0x81, 0x80, 0x80, 0x80, 0x80, 0x80,
664                                          0x80, 0x80, 0x80, 0x00 };
665   delta_window_header_[0] |= VCD_CHECKSUM;
666   delta_window_header_.append(kInvalidVarint, sizeof(kInvalidVarint));
667   // Adjust delta window size to include size of invalid Varint.
668   string size_of_invalid_varint;
669   VarintBE<int32_t>::AppendToString(
670       static_cast<int32_t>(delta_window_header_[4] + sizeof(kInvalidVarint)),
671       &size_of_invalid_varint);
672   delta_window_header_.replace(4, 1, size_of_invalid_varint);
673   InitializeDeltaFile();
674   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
675   bool failed = false;
676   for (size_t i = 0; i < delta_file_.size(); ++i) {
677     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
678       failed = true;
679       // It should fail while trying to interpret the checksum.
680       EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() - 2, i);
681       break;
682     }
683   }
684   EXPECT_TRUE(failed);
685   // The decoder should not create more target bytes than were expected.
686   EXPECT_GE(expected_target_.size(), output_.size());
687 }
688 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,TargetMatchesWindowSizeLimit)689 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesWindowSizeLimit) {
690   decoder_.SetMaximumTargetWindowSize(expected_target_.size());
691   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
692   for (size_t i = 0; i < delta_file_.size(); ++i) {
693     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
694   }
695   EXPECT_TRUE(decoder_.FinishDecoding());
696   EXPECT_EQ(expected_target_.c_str(), output_);
697 }
698 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,TargetMatchesFileSizeLimit)699 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesFileSizeLimit) {
700   decoder_.SetMaximumTargetFileSize(expected_target_.size());
701   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
702   for (size_t i = 0; i < delta_file_.size(); ++i) {
703     EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
704   }
705   EXPECT_TRUE(decoder_.FinishDecoding());
706   EXPECT_EQ(expected_target_.c_str(), output_);
707 }
708 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,TargetExceedsWindowSizeLimit)709 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsWindowSizeLimit) {
710   decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
711   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
712   bool failed = false;
713   for (size_t i = 0; i < delta_file_.size(); ++i) {
714     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
715       failed = true;
716       break;
717     }
718   }
719   EXPECT_TRUE(failed);
720   EXPECT_EQ("", output_);
721 }
722 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,TargetExceedsFileSizeLimit)723 TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsFileSizeLimit) {
724   decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
725   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
726   bool failed = false;
727   for (size_t i = 0; i < delta_file_.size(); ++i) {
728     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
729       failed = true;
730       break;
731     }
732   }
733   EXPECT_TRUE(failed);
734   EXPECT_EQ("", output_);
735 }
736 
737 // Fuzz bits to make sure decoder does not violently crash.
738 // This test has no expected behavior except that no crashes should occur.
739 // In some cases, changing bits will still decode to the correct target;
740 // for example, changing unused bits within a bitfield.
TEST_F(VCDiffInterleavedDecoderTestByteByByte,FuzzBits)741 TEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBits) {
742   while (FuzzOneByteInDeltaFile()) {
743     decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
744     bool failed = false;
745     for (size_t i = 0; i < delta_file_.size(); ++i) {
746       if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
747         failed = true;
748         break;
749       }
750     }
751     if (!failed) {
752       decoder_.FinishDecoding();
753     }
754     InitializeDeltaFile();
755     output_.clear();
756   }
757 }
758 
759 // If a checksum is present, then fuzzing any of the bits may produce an error,
760 // but it should not result in an incorrect target being produced without
761 // an error.
TEST_F(VCDiffInterleavedDecoderTestByteByByte,FuzzBitsWithChecksum)762 TEST_F(VCDiffInterleavedDecoderTestByteByByte, FuzzBitsWithChecksum) {
763   ComputeAndAddChecksum();
764   InitializeDeltaFile();
765   while (FuzzOneByteInDeltaFile()) {
766     decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
767     bool failed = false;
768     for (size_t i = 0; i < delta_file_.size(); ++i) {
769       if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
770         failed = true;
771         break;
772       }
773     }
774     if (!failed) {
775       if (decoder_.FinishDecoding()) {
776         // Decoding succeeded.  Make sure the correct target was produced.
777         EXPECT_EQ(expected_target_.c_str(), output_);
778       }
779     }
780     // The decoder should not create more target bytes than were expected.
781     EXPECT_GE(expected_target_.size(), output_.size());
782     InitializeDeltaFile();
783     output_.clear();
784   }
785 }
786 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyInstructionsShouldFailIfNoSourceSegment)787 TEST_F(VCDiffInterleavedDecoderTestByteByByte,
788        CopyInstructionsShouldFailIfNoSourceSegment) {
789   // Replace the Win_Indicator and the source size and source offset with a
790   // single 0 byte (a Win_Indicator for a window with no source segment.)
791   delta_window_header_.replace(0, 4, "\0", 1);
792   InitializeDeltaFile();
793   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
794   bool failed = false;
795   for (size_t i = 0; i < delta_file_.size(); ++i) {
796     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
797       failed = true;
798       // The first COPY instruction should fail.
799       EXPECT_EQ(delta_file_header_.size() + delta_window_header_.size() + 2, i);
800       break;
801     }
802   }
803   EXPECT_TRUE(failed);
804   EXPECT_EQ("", output_);
805 }
806 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyMoreThanExpectedTarget)807 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyMoreThanExpectedTarget) {
808   delta_file_[delta_file_header_.size() + 0x0C] =
809       FirstByteOfStringLength(kExpectedTarget);
810   delta_file_[delta_file_header_.size() + 0x0D] =
811       SecondByteOfStringLength(kExpectedTarget) + 1;
812   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
813   bool failed = false;
814   for (size_t i = 0; i < delta_file_.size(); ++i) {
815     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
816       failed = true;
817       // It should fail at the position that was altered
818       EXPECT_EQ(delta_file_header_.size() + 0x0D, i);
819       break;
820     }
821   }
822   EXPECT_TRUE(failed);
823   // The decoder should not create more target bytes than were expected.
824   EXPECT_GE(expected_target_.size(), output_.size());
825 }
826 
827 // A COPY instruction with an explicit size of 0 is not illegal according to the
828 // standard, although it is inefficient and should not be generated by any
829 // reasonable encoder.  Changing the size of a COPY instruction to zero will
830 // cause a failure because the generated target window size will not match the
831 // expected target size.
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeZero)832 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeZero) {
833   delta_file_[delta_file_header_.size() + 0x0C] = 0;
834   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
835   bool failed = false;
836   for (size_t i = 0; i < delta_file_.size(); ++i) {
837     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
838       failed = true;
839       break;
840     }
841   }
842   EXPECT_TRUE(failed);
843   // The decoder should not create more target bytes than were expected.
844   EXPECT_GE(expected_target_.size(), output_.size());
845 }
846 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeTooLargeByOne)847 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooLargeByOne) {
848   ++delta_file_[delta_file_header_.size() + 0x0C];
849   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
850   bool failed = false;
851   for (size_t i = 0; i < delta_file_.size(); ++i) {
852     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
853       failed = true;
854       break;
855     }
856   }
857   EXPECT_TRUE(failed);
858   // The decoder should not create more target bytes than were expected.
859   EXPECT_GE(expected_target_.size(), output_.size());
860 }
861 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeTooSmallByOne)862 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeTooSmallByOne) {
863   --delta_file_[delta_file_header_.size() + 0x0C];
864   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
865   bool failed = false;
866   for (size_t i = 0; i < delta_file_.size(); ++i) {
867     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
868       failed = true;
869       break;
870     }
871   }
872   EXPECT_TRUE(failed);
873   // The decoder should not create more target bytes than were expected.
874   EXPECT_GE(expected_target_.size(), output_.size());
875 }
876 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeMaxInt)877 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeMaxInt) {
878   WriteMaxVarintAtOffset(0x0C, 1);
879   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
880   bool failed = false;
881   for (size_t i = 0; i < delta_file_.size(); ++i) {
882     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
883       failed = true;
884       // It should fail at the position that was altered
885       EXPECT_EQ(delta_file_header_.size() + 0x10, i);
886       break;
887     }
888   }
889   EXPECT_TRUE(failed);
890   // The decoder should not create more target bytes than were expected.
891   EXPECT_GE(expected_target_.size(), output_.size());
892 }
893 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeNegative)894 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeNegative) {
895   WriteNegativeVarintAtOffset(0x0C, 1);
896   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
897   bool failed = false;
898   for (size_t i = 0; i < delta_file_.size(); ++i) {
899     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
900       failed = true;
901       // It should fail at the position that was altered
902       EXPECT_EQ(delta_file_header_.size() + 0x0F, i);
903       break;
904     }
905   }
906   EXPECT_TRUE(failed);
907   // The decoder should not create more target bytes than were expected.
908   EXPECT_GE(expected_target_.size(), output_.size());
909 }
910 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopySizeInvalid)911 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeInvalid) {
912   WriteInvalidVarintAtOffset(0x0C, 1);
913   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
914   bool failed = false;
915   for (size_t i = 0; i < delta_file_.size(); ++i) {
916     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
917       failed = true;
918       // It should fail at the position that was altered
919       EXPECT_EQ(delta_file_header_.size() + 0x10, i);
920       break;
921     }
922   }
923   EXPECT_TRUE(failed);
924   // The decoder should not create more target bytes than were expected.
925   EXPECT_GE(expected_target_.size(), output_.size());
926 }
927 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyAddressBeyondHereAddress)928 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressBeyondHereAddress) {
929   delta_file_[delta_file_header_.size() + 0x0D] =
930       FirstByteOfStringLength(kDictionary);
931   delta_file_[delta_file_header_.size() + 0x0E] =
932       SecondByteOfStringLength(kDictionary);
933   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
934   bool failed = false;
935   for (size_t i = 0; i < delta_file_.size(); ++i) {
936     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
937       failed = true;
938       // It should fail at the position that was altered
939       EXPECT_EQ(delta_file_header_.size() + 0x0E, i);
940       break;
941     }
942   }
943   EXPECT_TRUE(failed);
944   // The decoder should not create more target bytes than were expected.
945   EXPECT_GE(expected_target_.size(), output_.size());
946 }
947 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyAddressMaxInt)948 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressMaxInt) {
949   WriteMaxVarintAtOffset(0x0D, 1);
950   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
951   bool failed = false;
952   for (size_t i = 0; i < delta_file_.size(); ++i) {
953     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
954       failed = true;
955       // It should fail at the position that was altered
956       EXPECT_EQ(delta_file_header_.size() + 0x11, i);
957       break;
958     }
959   }
960   EXPECT_TRUE(failed);
961   // The decoder should not create more target bytes than were expected.
962   EXPECT_GE(expected_target_.size(), output_.size());
963 }
964 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyAddressNegative)965 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressNegative) {
966   WriteNegativeVarintAtOffset(0x0D, 1);
967   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
968   bool failed = false;
969   for (size_t i = 0; i < delta_file_.size(); ++i) {
970     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
971       failed = true;
972       // It should fail at the position that was altered
973       EXPECT_EQ(delta_file_header_.size() + 0x10, i);
974       break;
975     }
976   }
977   EXPECT_TRUE(failed);
978   // The decoder should not create more target bytes than were expected.
979   EXPECT_GE(expected_target_.size(), output_.size());
980 }
981 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,CopyAddressInvalid)982 TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressInvalid) {
983   WriteInvalidVarintAtOffset(0x0D, 1);
984   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
985   bool failed = false;
986   for (size_t i = 0; i < delta_file_.size(); ++i) {
987     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
988       failed = true;
989       // It should fail at the position that was altered
990       EXPECT_EQ(delta_file_header_.size() + 0x11, i);
991       break;
992     }
993   }
994   EXPECT_TRUE(failed);
995   // The decoder should not create more target bytes than were expected.
996   EXPECT_GE(expected_target_.size(), output_.size());
997 }
998 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddMoreThanExpectedTarget)999 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddMoreThanExpectedTarget) {
1000   delta_file_[delta_file_header_.size() + 0x0F] =
1001       FirstByteOfStringLength(kExpectedTarget);
1002   delta_file_[delta_file_header_.size() + 0x10] =
1003       SecondByteOfStringLength(kExpectedTarget) + 1;
1004   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1005   bool failed = false;
1006   for (size_t i = 0; i < delta_file_.size(); ++i) {
1007     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1008       failed = true;
1009       // It should fail at the position that was altered
1010       EXPECT_EQ(delta_file_header_.size() + 0x10, i);
1011       break;
1012     }
1013   }
1014   EXPECT_TRUE(failed);
1015   // The decoder should not create more target bytes than were expected.
1016   EXPECT_GE(expected_target_.size(), output_.size());
1017 }
1018 
1019 // An ADD instruction with an explicit size of 0 is not illegal according to the
1020 // standard, although it is inefficient and should not be generated by any
1021 // reasonable encoder.  Changing the size of an ADD instruction to zero will
1022 // cause a failure because the generated target window size will not match the
1023 // expected target size.
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeZero)1024 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeZero) {
1025   delta_file_[delta_file_header_.size() + 0x0F] = 0;
1026   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1027   bool failed = false;
1028   for (size_t i = 0; i < delta_file_.size(); ++i) {
1029     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1030       failed = true;
1031       break;
1032     }
1033   }
1034   EXPECT_TRUE(failed);
1035   // The decoder should not create more target bytes than were expected.
1036   EXPECT_GE(expected_target_.size(), output_.size());
1037 }
1038 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeTooLargeByOne)1039 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooLargeByOne) {
1040   ++delta_file_[delta_file_header_.size() + 0x0F];
1041   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1042   bool failed = false;
1043   for (size_t i = 0; i < delta_file_.size(); ++i) {
1044     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1045       failed = true;
1046       break;
1047     }
1048   }
1049   EXPECT_TRUE(failed);
1050   // The decoder should not create more target bytes than were expected.
1051   EXPECT_GE(expected_target_.size(), output_.size());
1052 }
1053 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeTooSmallByOne)1054 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeTooSmallByOne) {
1055   --delta_file_[delta_file_header_.size() + 0x0F];
1056   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1057   bool failed = false;
1058   for (size_t i = 0; i < delta_file_.size(); ++i) {
1059     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1060       failed = true;
1061       break;
1062     }
1063   }
1064   EXPECT_TRUE(failed);
1065   // The decoder should not create more target bytes than were expected.
1066   EXPECT_GE(expected_target_.size(), output_.size());
1067 }
1068 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeMaxInt)1069 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeMaxInt) {
1070   WriteMaxVarintAtOffset(0x0F, 1);
1071   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1072   bool failed = false;
1073   for (size_t i = 0; i < delta_file_.size(); ++i) {
1074     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1075       failed = true;
1076       // It should fail at the position that was altered
1077       EXPECT_EQ(delta_file_header_.size() + 0x13, i);
1078       break;
1079     }
1080   }
1081   EXPECT_TRUE(failed);
1082   // The decoder should not create more target bytes than were expected.
1083   EXPECT_GE(expected_target_.size(), output_.size());
1084 }
1085 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeNegative)1086 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeNegative) {
1087   WriteNegativeVarintAtOffset(0x0F, 1);
1088   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1089   bool failed = false;
1090   for (size_t i = 0; i < delta_file_.size(); ++i) {
1091     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1092       failed = true;
1093       // It should fail at the position that was altered
1094       EXPECT_EQ(delta_file_header_.size() + 0x12, i);
1095       break;
1096     }
1097   }
1098   EXPECT_TRUE(failed);
1099   // The decoder should not create more target bytes than were expected.
1100   EXPECT_GE(expected_target_.size(), output_.size());
1101 }
1102 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,AddSizeInvalid)1103 TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeInvalid) {
1104   WriteInvalidVarintAtOffset(0x0F, 1);
1105   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1106   bool failed = false;
1107   for (size_t i = 0; i < delta_file_.size(); ++i) {
1108     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1109       failed = true;
1110       // It should fail at the position that was altered
1111       EXPECT_EQ(delta_file_header_.size() + 0x13, i);
1112       break;
1113     }
1114   }
1115   EXPECT_TRUE(failed);
1116   // The decoder should not create more target bytes than were expected.
1117   EXPECT_GE(expected_target_.size(), output_.size());
1118 }
1119 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunMoreThanExpectedTarget)1120 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunMoreThanExpectedTarget) {
1121   delta_file_[delta_file_header_.size() + 0x5F] =
1122       FirstByteOfStringLength(kExpectedTarget);
1123   delta_file_[delta_file_header_.size() + 0x60] =
1124       SecondByteOfStringLength(kExpectedTarget) + 1;
1125   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1126   bool failed = false;
1127   for (size_t i = 0; i < delta_file_.size(); ++i) {
1128     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1129       failed = true;
1130       // It should fail at the position that was altered
1131       EXPECT_EQ(delta_file_header_.size() + 0x60, i);
1132       break;
1133     }
1134   }
1135   EXPECT_TRUE(failed);
1136   // The decoder should not create more target bytes than were expected.
1137   EXPECT_GE(expected_target_.size(), output_.size());
1138 }
1139 
1140 // A RUN instruction with an explicit size of 0 is not illegal according to the
1141 // standard, although it is inefficient and should not be generated by any
1142 // reasonable encoder.  Changing the size of a RUN instruction to zero will
1143 // cause a failure because the generated target window size will not match the
1144 // expected target size.
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeZero)1145 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeZero) {
1146   delta_file_[delta_file_header_.size() + 0x5F] = 0;
1147   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1148   bool failed = false;
1149   for (size_t i = 0; i < delta_file_.size(); ++i) {
1150     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1151       failed = true;
1152       break;
1153     }
1154   }
1155   EXPECT_TRUE(failed);
1156   // The decoder should not create more target bytes than were expected.
1157   EXPECT_GE(expected_target_.size(), output_.size());
1158 }
1159 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeTooLargeByOne)1160 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooLargeByOne) {
1161   ++delta_file_[delta_file_header_.size() + 0x5F];
1162   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1163   bool failed = false;
1164   for (size_t i = 0; i < delta_file_.size(); ++i) {
1165     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1166       failed = true;
1167       break;
1168     }
1169   }
1170   EXPECT_TRUE(failed);
1171   // The decoder should not create more target bytes than were expected.
1172   EXPECT_GE(expected_target_.size(), output_.size());
1173 }
1174 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeTooSmallByOne)1175 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeTooSmallByOne) {
1176   --delta_file_[delta_file_header_.size() + 0x5F];
1177   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1178   bool failed = false;
1179   for (size_t i = 0; i < delta_file_.size(); ++i) {
1180     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1181       failed = true;
1182       break;
1183     }
1184   }
1185   EXPECT_TRUE(failed);
1186   // The decoder should not create more target bytes than were expected.
1187   EXPECT_GE(expected_target_.size(), output_.size());
1188 }
1189 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeMaxInt)1190 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeMaxInt) {
1191   WriteMaxVarintAtOffset(0x5F, 1);
1192   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1193   bool failed = false;
1194   for (size_t i = 0; i < delta_file_.size(); ++i) {
1195     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1196       failed = true;
1197       // It should fail at the position that was altered
1198       EXPECT_EQ(delta_file_header_.size() + 0x63, i);
1199       break;
1200     }
1201   }
1202   EXPECT_TRUE(failed);
1203   // The decoder should not create more target bytes than were expected.
1204   EXPECT_GE(expected_target_.size(), output_.size());
1205 }
1206 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeNegative)1207 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeNegative) {
1208   WriteNegativeVarintAtOffset(0x5F, 1);
1209   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1210   bool failed = false;
1211   for (size_t i = 0; i < delta_file_.size(); ++i) {
1212     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1213       failed = true;
1214       // It should fail at the position that was altered
1215       EXPECT_EQ(delta_file_header_.size() + 0x62, i);
1216       break;
1217     }
1218   }
1219   EXPECT_TRUE(failed);
1220   // The decoder should not create more target bytes than were expected.
1221   EXPECT_GE(expected_target_.size(), output_.size());
1222 }
1223 
TEST_F(VCDiffInterleavedDecoderTestByteByByte,RunSizeInvalid)1224 TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeInvalid) {
1225   WriteInvalidVarintAtOffset(0x5F, 1);
1226   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
1227   bool failed = false;
1228   for (size_t i = 0; i < delta_file_.size(); ++i) {
1229     if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
1230       failed = true;
1231       // It should fail at the position that was altered
1232       EXPECT_EQ(delta_file_header_.size() + 0x63, i);
1233       break;
1234     }
1235   }
1236   EXPECT_TRUE(failed);
1237   // The decoder should not create more target bytes than were expected.
1238   EXPECT_GE(expected_target_.size(), output_.size());
1239 }
1240 
1241 }  // namespace open_vcdiff
1242