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