Skip to content

Commit

Permalink
programs: add regression test for overread check
Browse files Browse the repository at this point in the history
Update #157
  • Loading branch information
ebiggers committed Feb 6, 2022
1 parent dfcd156 commit fc9fe7b
Showing 1 changed file with 95 additions and 0 deletions.
95 changes: 95 additions & 0 deletions programs/test_overread.c
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;
}

0 comments on commit fc9fe7b

Please sign in to comment.