-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
programs: add regression test for overread check
Update #157
- Loading branch information
Showing
1 changed file
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* test_overread.c | ||
* | ||
* Test that the decompressor doesn't produce an unbounded amount of output if | ||
* it runs out of input, even when implicit zeroes appended to the input would | ||
* continue producing output (as is the case when the input ends during a | ||
* DYNAMIC_HUFFMAN block where a literal has an all-zeroes codeword). | ||
* | ||
* This is a regression test for commit 3f21ec9d6121 ("deflate_decompress: error | ||
* out if overread count gets too large"). | ||
*/ | ||
|
||
#include "test_util.h" | ||
|
||
static void | ||
generate_test_input(struct output_bitstream *os) | ||
{ | ||
int i; | ||
|
||
put_bits(os, 0, 1); /* BFINAL: 0 */ | ||
put_bits(os, 2, 2); /* BTYPE: DYNAMIC_HUFFMAN */ | ||
|
||
/* | ||
* Write the Huffman codes. | ||
* | ||
* Litlen code: | ||
* litlensym_0 (0) len=1 codeword=0 | ||
* litlensym_256 (end-of-block) len=1 codeword=1 | ||
* Offset code: | ||
* offsetsym_0 (unused) len=1 codeword=0 | ||
* | ||
* Litlen and offset codeword lengths: | ||
* [0] = 1 presym_1 | ||
* [1..255] = 0 presym_{18,18} | ||
* [256] = 1 presym_1 | ||
* [257] = 1 presym_1 | ||
* | ||
* Precode: | ||
* presym_1 len=1 codeword=0 | ||
* presym_18 len=1 codeword=1 | ||
*/ | ||
put_bits(os, 0, 5); /* num_litlen_syms: 0 + 257 */ | ||
put_bits(os, 0, 5); /* num_offset_syms: 0 + 1 */ | ||
put_bits(os, 14, 4); /* num_explicit_precode_lens: 14 + 4 */ | ||
/* | ||
* Precode codeword lengths: order is | ||
* [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] | ||
*/ | ||
put_bits(os, 0, 3); /* presym_16: len=0 */ | ||
put_bits(os, 0, 3); /* presym_17: len=0 */ | ||
put_bits(os, 1, 3); /* presym_18: len=1 */ | ||
for (i = 0; i < 14; i++) /* presym_{0,...,14}: len=0 */ | ||
put_bits(os, 0, 3); | ||
put_bits(os, 1, 3); /* presym_1: len=1 */ | ||
|
||
/* Litlen and offset codeword lengths */ | ||
put_bits(os, 0, 1); /* presym_1 */ | ||
put_bits(os, 1, 1); /* presym_18 ... */ | ||
put_bits(os, 117, 7); /* ... 11 + 117 zeroes */ | ||
put_bits(os, 1, 1); /* presym_18 ... */ | ||
put_bits(os, 116, 7); /* ... 11 + 116 zeroes */ | ||
put_bits(os, 0, 1); /* presym_1 */ | ||
put_bits(os, 0, 1); /* presym_1 */ | ||
|
||
/* Implicit zeroes would generate endless literals from here. */ | ||
|
||
ASSERT(flush_bits(os)); | ||
} | ||
|
||
int | ||
tmain(int argc, tchar *argv[]) | ||
{ | ||
u8 cdata[16]; | ||
u8 udata[256]; | ||
struct output_bitstream os = | ||
{ .next = cdata, .end = cdata + sizeof(cdata) }; | ||
struct libdeflate_decompressor *d; | ||
enum libdeflate_result res; | ||
size_t actual_out_nbytes; | ||
|
||
begin_program(argv); | ||
|
||
generate_test_input(&os); | ||
d = libdeflate_alloc_decompressor(); | ||
ASSERT(d != NULL); | ||
|
||
res = libdeflate_deflate_decompress(d, cdata, os.next - cdata, | ||
udata, sizeof(udata), | ||
&actual_out_nbytes); | ||
/* Before the fix, the result was LIBDEFLATE_INSUFFICIENT_SPACE here. */ | ||
ASSERT(res == LIBDEFLATE_BAD_DATA); | ||
|
||
libdeflate_free_decompressor(d); | ||
return 0; | ||
} |