From e90463fb046988beea101f74e10d0fbfed1d4d3e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 21 May 2019 21:13:59 -0700 Subject: [PATCH] programs/gunzip: allocate at least one byte for decompressed data libdeflate's 'gunzip' program fails if the uncompressed file size is a nonzero multiple of 4 GiB because then the ISIZE field in the gzip file is 0, so gunzip allocates no space for the decompressed data. Then when libdeflate returns LIBDEFLATE_INSUFFICIENT_SPACE, gunzip doubles the buffer size which stays 0, causing it to report "file corrupt or too large to be processed by this program". While neither libdeflate nor its 'gunzip' program is designed for single gzip streams this large anyway, this particular bug can easily be fixed by always allocating at least one byte for the decompressed data. --- programs/gzip.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/programs/gzip.c b/programs/gzip.c index a08d415..258babc 100644 --- a/programs/gzip.c +++ b/programs/gzip.c @@ -200,7 +200,16 @@ do_decompress(struct libdeflate_decompressor *decompressor, goto out; } + /* + * Use the ISIZE field as a hint for the decompressed data size. It may + * need to be increased later, however, because the file may contain + * multiple gzip members and the particular ISIZE we happen to use may + * not be the largest; or the real size may be >= 4 GiB, causing ISIZE + * to overflow. In any case, make sure to allocate at least one byte. + */ uncompressed_size = load_u32_gzip(&compressed_data[compressed_size - 4]); + if (uncompressed_size == 0) + uncompressed_size = 1; do { if (uncompressed_data == NULL) {