do not expose internal state of [g]zip unpacker.
fix memory leak in inflate_gunzip.
This commit is contained in:
parent
447b543eaf
commit
cd42cb8df0
@ -45,9 +45,8 @@ typedef struct huft_s {
|
|||||||
} v;
|
} v;
|
||||||
} huft_t;
|
} huft_t;
|
||||||
|
|
||||||
/* Globally-visible data */
|
static off_t gunzip_bytes_out; /* number of output bytes */
|
||||||
off_t gunzip_bytes_out; /* number of output bytes */
|
static uint32_t gunzip_crc;
|
||||||
uint32_t gunzip_crc;
|
|
||||||
|
|
||||||
static int gunzip_src_fd;
|
static int gunzip_src_fd;
|
||||||
static unsigned gunzip_outbuf_count; /* bytes in output buffer */
|
static unsigned gunzip_outbuf_count; /* bytes in output buffer */
|
||||||
@ -165,8 +164,7 @@ static int huft_free(huft_t * t)
|
|||||||
* t: result: starting table
|
* t: result: starting table
|
||||||
* m: maximum lookup bits, returns actual
|
* m: maximum lookup bits, returns actual
|
||||||
*/
|
*/
|
||||||
static
|
static int huft_build(unsigned *b, const unsigned n,
|
||||||
int huft_build(unsigned *b, const unsigned n,
|
|
||||||
const unsigned s, const unsigned short *d,
|
const unsigned s, const unsigned short *d,
|
||||||
const unsigned char *e, huft_t ** t, unsigned *m)
|
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
|
return 1; // We have a block to read
|
||||||
}
|
}
|
||||||
} else { /* it's an EOB or a length */
|
} else { /* it's an EOB or a length */
|
||||||
|
|
||||||
/* exit if end of block */
|
/* exit if end of block */
|
||||||
if (e == 15) {
|
if (e == 15) {
|
||||||
break;
|
break;
|
||||||
@ -595,11 +592,11 @@ static int inflate_block(int *e)
|
|||||||
inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
|
inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
case 1: /* Inflate fixed
|
case 1:
|
||||||
* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
/* Inflate fixed
|
||||||
* either replace this with a custom decoder, or at least precompute the
|
* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||||
* Huffman tables.
|
* either replace this with a custom decoder, or at least precompute the
|
||||||
*/
|
* Huffman tables. */
|
||||||
{
|
{
|
||||||
int i; /* temporary variable */
|
int i; /* temporary variable */
|
||||||
huft_t *tl; /* literal/length code table */
|
huft_t *tl; /* literal/length code table */
|
||||||
@ -854,25 +851,10 @@ static int inflate_get_next_window(void)
|
|||||||
/* Doesnt get here */
|
/* 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 */
|
/* Called from inflate_gunzip() and archival/unzip.c */
|
||||||
USE_DESKTOP(long long) int
|
static USE_DESKTOP(long long) int
|
||||||
inflate_unzip(int in, int out)
|
inflate_unzip_internal(int in, int out)
|
||||||
{
|
{
|
||||||
USE_DESKTOP(long long total = 0;)
|
USE_DESKTOP(long long total = 0;)
|
||||||
ssize_t nwrote;
|
ssize_t nwrote;
|
||||||
@ -922,14 +904,35 @@ inflate_unzip(int in, int out)
|
|||||||
return USE_DESKTOP(total) + 0;
|
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
|
USE_DESKTOP(long long) int
|
||||||
inflate_gunzip(int in, int out)
|
inflate_gunzip(int in, int out)
|
||||||
{
|
{
|
||||||
uint32_t stored_crc = 0;
|
uint32_t stored_crc = 0;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
USE_DESKTOP(long long total = )inflate_unzip(in, out);
|
USE_DESKTOP(long long) int n;
|
||||||
|
|
||||||
USE_DESKTOP(if (total < 0) return total;)
|
n = inflate_unzip_internal(in, out);
|
||||||
|
|
||||||
|
if (n < 0) goto ret;
|
||||||
|
|
||||||
/* top up the input buffer with the rest of the trailer */
|
/* top up the input buffer with the rest of the trailer */
|
||||||
count = bytebuffer_size - bytebuffer_offset;
|
count = bytebuffer_size - bytebuffer_offset;
|
||||||
@ -946,7 +949,8 @@ inflate_gunzip(int in, int out)
|
|||||||
/* Validate decompression - crc */
|
/* Validate decompression - crc */
|
||||||
if (stored_crc != (~gunzip_crc)) {
|
if (stored_crc != (~gunzip_crc)) {
|
||||||
bb_error_msg("crc error");
|
bb_error_msg("crc error");
|
||||||
return -1;
|
n = -1;
|
||||||
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate decompression - size */
|
/* Validate decompression - size */
|
||||||
@ -955,8 +959,9 @@ inflate_gunzip(int in, int out)
|
|||||||
(bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))
|
(bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))
|
||||||
) {
|
) {
|
||||||
bb_error_msg("incorrect length");
|
bb_error_msg("incorrect length");
|
||||||
return -1;
|
n = -1;
|
||||||
}
|
}
|
||||||
|
ret:
|
||||||
return USE_DESKTOP(total) + 0;
|
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);
|
bb_copyfd_exact_size(src_fd, dst_fd, size);
|
||||||
} else {
|
} else {
|
||||||
/* Method 8 - inflate */
|
/* Method 8 - inflate */
|
||||||
inflate_init(zip_header->formatted.cmpsize);
|
inflate_unzip_result res;
|
||||||
inflate_unzip(src_fd, dst_fd);
|
/* err = */ inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd);
|
||||||
inflate_cleanup();
|
// we should check for -1 error return
|
||||||
/* Validate decompression - crc */
|
/* 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");
|
bb_error_msg("invalid compressed data--%s error", "crc");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Validate decompression - size */
|
/* 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");
|
bb_error_msg("invalid compressed data--%s error", "length");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,6 @@ typedef struct archive_handle_s {
|
|||||||
} archive_handle_t;
|
} archive_handle_t;
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t gunzip_crc;
|
|
||||||
extern off_t gunzip_bytes_out;
|
|
||||||
|
|
||||||
|
|
||||||
extern archive_handle_t *init_handle(void);
|
extern archive_handle_t *init_handle(void);
|
||||||
|
|
||||||
extern char filter_accept_all(archive_handle_t *archive_handle);
|
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 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 USE_DESKTOP(long long) int uncompressStream(int src_fd, int dst_fd);
|
||||||
extern void inflate_init(unsigned int bufsize);
|
|
||||||
extern void inflate_cleanup(void);
|
typedef struct inflate_unzip_result {
|
||||||
extern USE_DESKTOP(long long) int inflate_unzip(int in, int out);
|
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 inflate_gunzip(int in, int out);
|
||||||
extern USE_DESKTOP(long long) int unlzma(int src_fd, int dst_fd);
|
extern USE_DESKTOP(long long) int unlzma(int src_fd, int dst_fd);
|
||||||
|
|
||||||
extern int open_transformer(int src_fd,
|
extern int open_transformer(int src_fd,
|
||||||
USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd));
|
USE_DESKTOP(long long) int (*transformer)(int src_fd, int dst_fd));
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user