do not expose internal state of [g]zip unpacker. fix memory leak in inflate_gunzip.
No binary (build failed)
—
(log yok)
| @@ -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; |
| } | |
| @@ -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; | |
| } | |
| @@ -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 | |