do not expose internal state of [g]zip unpacker.
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 5 Jan 2007 23:56:53 +0000 (23:56 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 5 Jan 2007 23:56:53 +0000 (23:56 -0000)
fix memory leak in inflate_gunzip.

archival/libunarchive/decompress_unzip.c
archival/unzip.c
include/unarchive.h

index 7001c70f92caeef691a75ee7794da61cd8effcfa..af74e6598576a9622f86bb74a9109cc52d645b41 100644 (file)
@@ -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;
 }
index 34a3a8519ece88258bba94cd1c081a0470b6fe34..b10132ebde4eb1b69e9eba3c3c152ca063bb798a 100644 (file)
@@ -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;
                }
index 843f68f73a677c7bbd792e1ca33bb061f3342cbc..5e87d088e068f0f0c60d2de403091126ab4c6449 100644 (file)
@@ -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