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
42namespace open_vcdiff {
43
44// Test headers, valid and invalid.
45
46TEST_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
55TEST_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
64TEST_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
73TEST_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
82TEST_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
91TEST_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
100TEST_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
111TEST_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
121TEST_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().
142TEST_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
152TEST_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
163TEST_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
173TEST_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
183TEST_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
192TEST_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.
205TEST_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.
221TEST_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
241TEST_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
253TEST_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
262TEST_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
271TEST_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
280TEST_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
289TEST_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
298TEST_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
307TEST_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
319TEST_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
328TEST_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
337TEST_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
346TEST_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
358TEST_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
367TEST_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
376TEST_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
385TEST_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
394TEST_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
403TEST_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
412TEST_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
424TEST_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
433TEST_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
442TEST_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
451TEST_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
460TEST_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
469TEST_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))
480TEST_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
513TEST_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
552typedef VCDiffInterleavedDecoderTest VCDiffInterleavedDecoderTestByteByByte;
553
554// Test headers, valid and invalid.
555
556TEST_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
565TEST_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
575TEST_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
591TEST_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
607TEST_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
624TEST_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
633TEST_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
644TEST_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
662TEST_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
689TEST_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
699TEST_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
709TEST_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
723TEST_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.
741TEST_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.
762TEST_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
787TEST_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
807TEST_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.
832TEST_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
847TEST_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
862TEST_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
877TEST_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
894TEST_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
911TEST_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
928TEST_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
948TEST_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
965TEST_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
982TEST_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
999TEST_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.
1024TEST_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
1039TEST_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
1054TEST_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
1069TEST_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
1086TEST_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
1103TEST_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
1120TEST_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.
1145TEST_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
1160TEST_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
1175TEST_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
1190TEST_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
1207TEST_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
1224TEST_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