From cd42cb8df066ffd4449af6de168190669dad4453 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 5 Jan 2007 23:56:53 +0000 Subject: do not expose internal state of [g]zip unpacker. fix memory leak in inflate_gunzip. --- archival/libunarchive/decompress_unzip.c | 73 +++++++++++++++++--------------- archival/unzip.c | 10 ++--- include/unarchive.h | 15 +++---- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 7001c70f9..af74e6598 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c @@ -45,9 +45,8 @@ typedef struct huft_s { } v; } huft_t; -/* Globally-visible data */ -off_t gunzip_bytes_out; /* number of output bytes */ -uint32_t gunzip_crc; +static off_t gunzip_bytes_out; /* number of output bytes */ +static uint32_t gunzip_crc; static int gunzip_src_fd; static unsigned gunzip_outbuf_count; /* bytes in output buffer */ @@ -165,8 +164,7 @@ static int huft_free(huft_t * t) * t: result: starting table * m: maximum lookup bits, returns actual */ -static -int huft_build(unsigned *b, const unsigned n, +static int huft_build(unsigned *b, const unsigned n, const unsigned s, const unsigned short *d, const unsigned char *e, huft_t ** t, unsigned *m) { @@ -408,7 +406,6 @@ static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, c return 1; // We have a block to read } } else { /* it's an EOB or a length */ - /* exit if end of block */ if (e == 15) { break; @@ -595,11 +592,11 @@ static int inflate_block(int *e) inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored return -1; } - case 1: /* Inflate fixed - * decompress an inflated type 1 (fixed Huffman codes) block. We should - * either replace this with a custom decoder, or at least precompute the - * Huffman tables. - */ + case 1: + /* Inflate fixed + * decompress an inflated type 1 (fixed Huffman codes) block. We should + * either replace this with a custom decoder, or at least precompute the + * Huffman tables. */ { int i; /* temporary variable */ huft_t *tl; /* literal/length code table */ @@ -854,25 +851,10 @@ static int inflate_get_next_window(void) /* Doesnt get here */ } -/* Initialize bytebuffer, be careful not to overfill the buffer */ -/* Called from archival/unzip.c */ -void inflate_init(unsigned bufsize) -{ - /* Set the bytebuffer size, default is same as gunzip_wsize */ - bytebuffer_max = bufsize + 8; - bytebuffer_offset = 4; - bytebuffer_size = 0; -} - -/* Called from archival/unzip.c */ -void inflate_cleanup(void) -{ - free(bytebuffer); -} /* Called from inflate_gunzip() and archival/unzip.c */ -USE_DESKTOP(long long) int -inflate_unzip(int in, int out) +static USE_DESKTOP(long long) int +inflate_unzip_internal(int in, int out) { USE_DESKTOP(long long total = 0;) ssize_t nwrote; @@ -922,14 +904,35 @@ inflate_unzip(int in, int out) return USE_DESKTOP(total) + 0; } + +USE_DESKTOP(long long) int +inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out) +{ + USE_DESKTOP(long long) int n; + + bytebuffer_max = bufsize + 8; + bytebuffer_offset = 4; + bytebuffer_size = 0; + + n = inflate_unzip_internal(in, out); + + res->crc = gunzip_crc; + res->bytes_out = gunzip_bytes_out; + free(bytebuffer); + return n; +} + + USE_DESKTOP(long long) int inflate_gunzip(int in, int out) { uint32_t stored_crc = 0; unsigned count; - USE_DESKTOP(long long total = )inflate_unzip(in, out); + USE_DESKTOP(long long) int n; + + n = inflate_unzip_internal(in, out); - USE_DESKTOP(if (total < 0) return total;) + if (n < 0) goto ret; /* top up the input buffer with the rest of the trailer */ count = bytebuffer_size - bytebuffer_offset; @@ -946,7 +949,8 @@ inflate_gunzip(int in, int out) /* Validate decompression - crc */ if (stored_crc != (~gunzip_crc)) { bb_error_msg("crc error"); - return -1; + n = -1; + goto ret; } /* Validate decompression - size */ @@ -955,8 +959,9 @@ inflate_gunzip(int in, int out) (bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24)) ) { bb_error_msg("incorrect length"); - return -1; + n = -1; } - - return USE_DESKTOP(total) + 0; + ret: + free(bytebuffer); + return n; } diff --git a/archival/unzip.c b/archival/unzip.c index 34a3a8519..b10132ebd 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -76,16 +76,16 @@ static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) bb_copyfd_exact_size(src_fd, dst_fd, size); } else { /* Method 8 - inflate */ - inflate_init(zip_header->formatted.cmpsize); - inflate_unzip(src_fd, dst_fd); - inflate_cleanup(); + inflate_unzip_result res; + /* err = */ inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd); +// we should check for -1 error return /* Validate decompression - crc */ - if (zip_header->formatted.crc32 != (gunzip_crc ^ 0xffffffffL)) { + if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { bb_error_msg("invalid compressed data--%s error", "crc"); return 1; } /* Validate decompression - size */ - if (zip_header->formatted.ucmpsize != gunzip_bytes_out) { + if (zip_header->formatted.ucmpsize != res.bytes_out) { bb_error_msg("invalid compressed data--%s error", "length"); return 1; } diff --git a/include/unarchive.h b/include/unarchive.h index 843f68f73..5e87d088e 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -65,10 +65,6 @@ typedef struct archive_handle_s { } archive_handle_t; -extern uint32_t gunzip_crc; -extern off_t gunzip_bytes_out; - - extern archive_handle_t *init_handle(void); extern char filter_accept_all(archive_handle_t *archive_handle); @@ -106,14 +102,17 @@ extern const llist_t *find_list_entry(const llist_t *list, const char *filename) extern const llist_t *find_list_entry2(const llist_t *list, const char *filename); extern USE_DESKTOP(long long) int uncompressStream(int src_fd, int dst_fd); -extern void inflate_init(unsigned int bufsize); -extern void inflate_cleanup(void); -extern USE_DESKTOP(long long) int inflate_unzip(int in, int out); + +typedef struct inflate_unzip_result { + off_t bytes_out; + uint32_t crc; +} inflate_unzip_result; + +extern USE_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out); extern USE_DESKTOP(long long) int inflate_gunzip(int in, int out); extern USE_DESKTOP(long long) int unlzma(int src_fd, int dst_fd); extern int open_transformer(int src_fd, USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd)); - #endif -- cgit v1.2.3