aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive/decompress_unzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libunarchive/decompress_unzip.c')
-rw-r--r--archival/libunarchive/decompress_unzip.c166
1 files changed, 94 insertions, 72 deletions
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index 046f4dd72..7ebbd0ee7 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -155,12 +155,6 @@ static unsigned int fill_bitbuffer(unsigned int bitbuffer, unsigned int *current
return(bitbuffer);
}
-static void abort_gzip(void)
-{
- error_msg("gzip aborted\n");
- exit(-1);
-}
-
static void make_gunzip_crc_table(void)
{
const unsigned int poly = 0xedb88320; /* polynomial exclusive-or pattern */
@@ -438,24 +432,37 @@ static void flush_gunzip_window(void)
* tl, td: literal/length and distance decoder tables
* bl, bd: number of bits decoded by tl[] and td[]
*/
-static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const unsigned int bd)
+static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup)
{
- unsigned int e; /* table entry flag/number of extra bits */
- unsigned int n, d; /* length and index for copy */
- unsigned int w; /* current gunzip_window position */
- huft_t *t; /* pointer to table entry */
- unsigned int ml, md; /* masks for bl and bd bits */
- unsigned int b; /* bit buffer */
- unsigned int k; /* number of bits in bit buffer */
-
- /* make local copies of globals */
- b = gunzip_bb; /* initialize bit buffer */
- k = gunzip_bk;
- w = gunzip_outbuf_count; /* initialize gunzip_window position */
-
- /* inflate the coded data */
- ml = mask_bits[bl]; /* precompute masks for speed */
- md = mask_bits[bd];
+ static unsigned int e; /* table entry flag/number of extra bits */
+ static unsigned int n, d; /* length and index for copy */
+ static unsigned int w; /* current gunzip_window position */
+ static huft_t *t; /* pointer to table entry */
+ static unsigned int ml, md; /* masks for bl and bd bits */
+ static unsigned int b; /* bit buffer */
+ static unsigned int k; /* number of bits in bit buffer */
+ static huft_t *tl, *td;
+ static unsigned int bl, bd;
+ static int resumeCopy = 0;
+
+ if (setup) { // 1st time we are called, copy in variables
+ tl = my_tl;
+ td = my_td;
+ bl = my_bl;
+ bd = my_bd;
+ /* make local copies of globals */
+ b = gunzip_bb; /* initialize bit buffer */
+ k = gunzip_bk;
+ w = gunzip_outbuf_count; /* initialize gunzip_window position */
+
+ /* inflate the coded data */
+ ml = mask_bits[bl]; /* precompute masks for speed */
+ md = mask_bits[bd];
+ return 0; // Don't actually do anything the first time
+ }
+
+ if (resumeCopy) goto do_copy;
+
while (1) { /* do until end of block */
b = fill_bitbuffer(b, &k, bl);
if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
@@ -475,8 +482,9 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
gunzip_window[w++] = (unsigned char) t->v.n;
if (w == gunzip_wsize) {
gunzip_outbuf_count = (w);
- flush_gunzip_window();
+ //flush_gunzip_window();
w = 0;
+ return -1;
}
} else { /* it's an EOB or a length */
@@ -512,7 +520,7 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
k -= e;
/* do the copy */
- do {
+do_copy: do {
n -= (e =
(e =
gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e);
@@ -530,11 +538,14 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
}
if (w == gunzip_wsize) {
gunzip_outbuf_count = (w);
- flush_gunzip_window();
+ if (n) resumeCopy = 1;
+ else resumeCopy = 0;
+ //flush_gunzip_window();
w = 0;
+ return -1;
}
-
} while (n);
+ resumeCopy = 0;
}
}
@@ -543,16 +554,56 @@ static int inflate_codes(huft_t * tl, huft_t * td, const unsigned int bl, const
gunzip_bb = b; /* restore global bit buffer */
gunzip_bk = k;
+ /* normally just after call to inflate_codes, but save code by putting it here */
+ /* free the decoding tables, return */
+ huft_free(tl);
+ huft_free(td);
+
/* done */
return 0;
}
+int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup)
+{
+ static int n, b_stored, k_stored, w;
+ if (setup) {
+ n = my_n;
+ b_stored = my_b_stored;
+ k_stored = my_k_stored;
+ w = gunzip_outbuf_count; /* initialize gunzip_window position */
+ return 0; // Don't do anything first time
+ }
+
+ /* read and output the compressed data */
+ while (n--) {
+ b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
+ gunzip_window[w++] = (unsigned char) b_stored;
+ if (w == (unsigned int) gunzip_wsize) {
+ gunzip_outbuf_count = (w);
+ //flush_gunzip_window();
+ w = 0;
+ b_stored >>= 8;
+ k_stored -= 8;
+ return -1; // Means more stuff 2do
+ }
+ b_stored >>= 8;
+ k_stored -= 8;
+ }
+
+ /* restore the globals from the locals */
+ gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
+ gunzip_bb = b_stored; /* restore global bit buffer */
+ gunzip_bk = k_stored;
+ return 0; // Finished
+}
+
/*
* decompress an inflated block
* e: last block flag
*
* GLOBAL VARIABLES: bb, kk,
*/
+ // Return values: -1 = inflate_stored, -2 = inflate_codes
static int inflate_block(int *e)
{
unsigned t; /* block type */
@@ -585,14 +636,12 @@ static int inflate_block(int *e)
case 0: /* Inflate stored */
{
unsigned int n; /* number of bytes in block */
- unsigned int w; /* current gunzip_window position */
unsigned int b_stored; /* bit buffer */
unsigned int k_stored; /* number of bits in bit buffer */
/* make local copies of globals */
b_stored = gunzip_bb; /* initialize bit buffer */
k_stored = gunzip_bk;
- w = gunzip_outbuf_count; /* initialize gunzip_window position */
/* go to byte boundary */
n = k_stored & 7;
@@ -612,24 +661,8 @@ static int inflate_block(int *e)
b_stored >>= 16;
k_stored -= 16;
- /* read and output the compressed data */
- while (n--) {
- b_stored = fill_bitbuffer(b_stored, &k_stored, 8);
- gunzip_window[w++] = (unsigned char) b_stored;
- if (w == (unsigned int) gunzip_wsize) {
- gunzip_outbuf_count = (w);
- flush_gunzip_window();
- w = 0;
- }
- b_stored >>= 8;
- k_stored -= 8;
- }
-
- /* restore the globals from the locals */
- gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
- gunzip_bb = b_stored; /* restore global bit buffer */
- gunzip_bk = k_stored;
- return 0;
+ 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
@@ -673,14 +706,11 @@ static int inflate_block(int *e)
}
/* decompress until an end-of-block code */
- if (inflate_codes(tl, td, bl, bd)) {
- return 1;
- }
-
- /* free the decoding tables, return */
- huft_free(tl);
- huft_free(td);
- return 0;
+ inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
+
+ /* huft_free code moved into inflate_codes */
+
+ return -2;
}
case 2: /* Inflate dynamic */
{
@@ -828,14 +858,11 @@ static int inflate_block(int *e)
}
/* decompress until an end-of-block code */
- if (inflate_codes(tl, td, bl, bd)) {
- return 1;
- }
+ inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes
- /* free the decoding tables, return */
- huft_free(tl);
- huft_free(td);
- return 0;
+ /* huft_free code moved into inflate_codes */
+
+ return -2;
}
default:
/* bad block type */
@@ -862,7 +889,11 @@ extern ssize_t read_gz(int fd, void *buf, size_t count)
if (e) return 0; // No more data here!
gunzip_hufts = 0;
r = inflate_block(&e);
- if (r != 0) {
+ if (r == -1) { // Call inflate_stored while returning -1
+ while(inflate_stored(0,0,0,0) == -1) flush_gunzip_window();
+ } else if (r == -2) { // Call inflate_codes while returning -1
+ while(inflate_codes(0,0,0,0,0) == -1) flush_gunzip_window();
+ } else {
error_msg_and_die("inflate error %d", r);
return -1;
}
@@ -895,15 +926,6 @@ extern void GZ_gzReadOpen(int fd, void *unused, int nUnused)
gunzip_in_buffer = malloc(8);
- if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
- (void) signal(SIGINT, (sig_type) abort_gzip);
- }
-#ifdef SIGHUP
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
- (void) signal(SIGHUP, (sig_type) abort_gzip);
- }
-#endif
-
/* initialize gunzip_window, bit buffer */
gunzip_bk = 0;
gunzip_bb = 0;