1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/*
* test_trailing_bytes.c
*
* Test that decompression correctly stops at the end of the first DEFLATE,
* zlib, or gzip stream, and doesn't process any additional trailing bytes.
*/
#include "test_util.h"
static const struct {
size_t (*compress)(struct libdeflate_compressor *compressor,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail);
enum libdeflate_result (*decompress)(
struct libdeflate_decompressor *decompressor,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_out_nbytes_ret);
enum libdeflate_result (*decompress_ex)(
struct libdeflate_decompressor *decompressor,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_in_nbytes_ret,
size_t *actual_out_nbytes_ret);
} codecs[] = {
{
.compress = libdeflate_deflate_compress,
.decompress = libdeflate_deflate_decompress,
.decompress_ex = libdeflate_deflate_decompress_ex,
}, {
.compress = libdeflate_zlib_compress,
.decompress = libdeflate_zlib_decompress,
.decompress_ex = libdeflate_zlib_decompress_ex,
}, {
.compress = libdeflate_gzip_compress,
.decompress = libdeflate_gzip_decompress,
.decompress_ex = libdeflate_gzip_decompress_ex,
}
};
int
tmain(int argc, tchar *argv[])
{
const size_t original_nbytes = 32768;
const size_t compressed_nbytes_total = 32768;
/*
* Don't use the full buffer for compressed data, because we want to
* test whether decompression can deal with additional trailing bytes.
*
* Note: we can't use a guarded buffer (i.e. a buffer where the byte
* after compressed_nbytes is unmapped) because the decompressor may
* read a few bytes beyond the end of the stream (but ultimately not
* actually use those bytes) as long as they are within the buffer.
*/
const size_t compressed_nbytes_avail = 30000;
size_t i;
u8 *original;
u8 *compressed;
u8 *decompressed;
struct libdeflate_compressor *c;
struct libdeflate_decompressor *d;
size_t compressed_nbytes;
enum libdeflate_result res;
size_t actual_compressed_nbytes;
size_t actual_decompressed_nbytes;
begin_program(argv);
ASSERT(compressed_nbytes_avail < compressed_nbytes_total);
/* Prepare some dummy data to compress */
original = xmalloc(original_nbytes);
ASSERT(original != NULL);
for (i = 0; i < original_nbytes; i++)
original[i] = (i % 123) + (i % 1023);
compressed = xmalloc(compressed_nbytes_total);
ASSERT(compressed != NULL);
memset(compressed, 0, compressed_nbytes_total);
decompressed = xmalloc(original_nbytes);
ASSERT(decompressed != NULL);
c = libdeflate_alloc_compressor(6);
ASSERT(c != NULL);
d = libdeflate_alloc_decompressor();
ASSERT(d != NULL);
for (i = 0; i < ARRAY_LEN(codecs); i++) {
compressed_nbytes = codecs[i].compress(c, original,
original_nbytes,
compressed,
compressed_nbytes_avail);
ASSERT(compressed_nbytes > 0);
ASSERT(compressed_nbytes <= compressed_nbytes_avail);
/* Test decompress() of stream that fills the whole buffer */
actual_decompressed_nbytes = 0;
memset(decompressed, 0, original_nbytes);
res = codecs[i].decompress(d, compressed, compressed_nbytes,
decompressed, original_nbytes,
&actual_decompressed_nbytes);
ASSERT(res == LIBDEFLATE_SUCCESS);
ASSERT(actual_decompressed_nbytes == original_nbytes);
ASSERT(memcmp(decompressed, original, original_nbytes) == 0);
/* Test decompress_ex() of stream that fills the whole buffer */
actual_compressed_nbytes = actual_decompressed_nbytes = 0;
memset(decompressed, 0, original_nbytes);
res = codecs[i].decompress_ex(d, compressed, compressed_nbytes,
decompressed, original_nbytes,
&actual_compressed_nbytes,
&actual_decompressed_nbytes);
ASSERT(res == LIBDEFLATE_SUCCESS);
ASSERT(actual_compressed_nbytes == compressed_nbytes);
ASSERT(actual_decompressed_nbytes == original_nbytes);
ASSERT(memcmp(decompressed, original, original_nbytes) == 0);
/* Test decompress() of stream with trailing bytes */
actual_decompressed_nbytes = 0;
memset(decompressed, 0, original_nbytes);
res = codecs[i].decompress(d, compressed,
compressed_nbytes_total,
decompressed, original_nbytes,
&actual_decompressed_nbytes);
ASSERT(res == LIBDEFLATE_SUCCESS);
ASSERT(actual_decompressed_nbytes == original_nbytes);
ASSERT(memcmp(decompressed, original, original_nbytes) == 0);
/* Test decompress_ex() of stream with trailing bytes */
actual_compressed_nbytes = actual_decompressed_nbytes = 0;
memset(decompressed, 0, original_nbytes);
res = codecs[i].decompress_ex(d, compressed,
compressed_nbytes_total,
decompressed, original_nbytes,
&actual_compressed_nbytes,
&actual_decompressed_nbytes);
ASSERT(res == LIBDEFLATE_SUCCESS);
ASSERT(actual_compressed_nbytes == compressed_nbytes);
ASSERT(actual_decompressed_nbytes == original_nbytes);
ASSERT(memcmp(decompressed, original, original_nbytes) == 0);
}
free(original);
free(compressed);
free(decompressed);
libdeflate_free_compressor(c);
libdeflate_free_decompressor(d);
return 0;
}
|