/* * test_litrunlen_overflow.c * * Regression test for commit f2f0df727444 ("deflate_compress: fix corruption * with long literal run"). Try to compress a file longer than 65535 bytes * where no 2-byte sequence (3 would be sufficient) is repeated <= 32768 bytes * apart, and the distribution of bytes remains constant throughout, and yet not * all bytes are used so the data is still slightly compressible. There will be * no matches in this data, but the compressor should still output a compressed * block, and this block should contain more than 65535 consecutive literals, * which triggered the bug. * * Note: on random data, this situation is extremely unlikely if the compressor * uses all matches it finds, since random data will on average have a 3-byte * match every (256**3)/32768 = 512 bytes. */ #include "test_util.h" int tmain(int argc, tchar *argv[]) { const int data_size = 2 * 250 * 251; u8 *orig_data, *compressed_data, *decompressed_data; int i, stride, multiple, j = 0; struct libdeflate_decompressor *d; static const int levels[] = { 3, 6, 12 }; begin_program(argv); orig_data = xmalloc(data_size); compressed_data = xmalloc(data_size); decompressed_data = xmalloc(data_size); for (i = 0; i < 2; i++) { for (stride = 1; stride < 251; stride++) { for (multiple = 0; multiple < 251; multiple++) orig_data[j++] = (stride * multiple) % 251; } } ASSERT(j == data_size); d = libdeflate_alloc_decompressor(); ASSERT(d != NULL); for (i = 0; i < ARRAY_LEN(levels); i++) { struct libdeflate_compressor *c; size_t csize; enum libdeflate_result res; c = libdeflate_alloc_compressor(levels[i]); ASSERT(c != NULL); csize = libdeflate_deflate_compress(c, orig_data, data_size, compressed_data, data_size); ASSERT(csize > 0 && csize < data_size); res = libdeflate_deflate_decompress(d, compressed_data, csize, decompressed_data, data_size, NULL); ASSERT(res == LIBDEFLATE_SUCCESS); ASSERT(memcmp(orig_data, decompressed_data, data_size) == 0); libdeflate_free_compressor(c); } libdeflate_free_decompressor(d); free(orig_data); free(compressed_data); free(decompressed_data); return 0; }