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