diff options
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 17b87e2c1..c1b12732c 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define RETVAL_LAST_BLOCK (-1) | 44 | #define RETVAL_LAST_BLOCK (-1) |
45 | #define RETVAL_NOT_BZIP_DATA (-2) | 45 | #define RETVAL_NOT_BZIP_DATA (-2) |
46 | #define RETVAL_UNEXPECTED_INPUT_EOF (-3) | 46 | #define RETVAL_UNEXPECTED_INPUT_EOF (-3) |
47 | #define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) | 47 | #define RETVAL_SHORT_WRITE (-4) |
48 | #define RETVAL_DATA_ERROR (-5) | 48 | #define RETVAL_DATA_ERROR (-5) |
49 | #define RETVAL_OUT_OF_MEMORY (-6) | 49 | #define RETVAL_OUT_OF_MEMORY (-6) |
50 | #define RETVAL_OBSOLETE_INPUT (-7) | 50 | #define RETVAL_OBSOLETE_INPUT (-7) |
@@ -54,22 +54,27 @@ | |||
54 | 54 | ||
55 | /* This is what we know about each Huffman coding group */ | 55 | /* This is what we know about each Huffman coding group */ |
56 | struct group_data { | 56 | struct group_data { |
57 | /* We have an extra slot at the end of limit[] for a sentinal value. */ | 57 | /* We have an extra slot at the end of limit[] for a sentinel value. */ |
58 | int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; | 58 | int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; |
59 | int minLen, maxLen; | 59 | int minLen, maxLen; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | /* Structure holding all the housekeeping data, including IO buffers and | 62 | /* Structure holding all the housekeeping data, including IO buffers and |
63 | memory that persists between calls to bunzip */ | 63 | * memory that persists between calls to bunzip |
64 | * Found the most used member: | ||
65 | * cat this_file.c | sed -e 's/"/ /g' -e "s/'/ /g" | xargs -n1 \ | ||
66 | * | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER | ||
67 | * and moved it (inbufBitCount) to offset 0. | ||
68 | */ | ||
64 | 69 | ||
65 | struct bunzip_data { | 70 | struct bunzip_data { |
66 | /* State for interrupting output loop */ | ||
67 | int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; | ||
68 | |||
69 | /* I/O tracking data (file handles, buffers, positions, etc.) */ | 71 | /* I/O tracking data (file handles, buffers, positions, etc.) */ |
72 | unsigned inbufBitCount, inbufBits; | ||
70 | int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; | 73 | int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; |
71 | unsigned char *inbuf /*,*outbuf*/; | 74 | unsigned char *inbuf /*,*outbuf*/; |
72 | unsigned inbufBitCount, inbufBits; | 75 | |
76 | /* State for interrupting output loop */ | ||
77 | int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; | ||
73 | 78 | ||
74 | /* The CRC values stored in the block header and calculated from the data */ | 79 | /* The CRC values stored in the block header and calculated from the data */ |
75 | uint32_t headerCRC, totalCRC, writeCRC; | 80 | uint32_t headerCRC, totalCRC, writeCRC; |
@@ -80,7 +85,7 @@ struct bunzip_data { | |||
80 | /* For I/O error handling */ | 85 | /* For I/O error handling */ |
81 | jmp_buf jmpbuf; | 86 | jmp_buf jmpbuf; |
82 | 87 | ||
83 | /* Big things go last (register-relative addressing can be larger for big offsets */ | 88 | /* Big things go last (register-relative addressing can be larger for big offsets) */ |
84 | uint32_t crc32Table[256]; | 89 | uint32_t crc32Table[256]; |
85 | unsigned char selectors[32768]; /* nSelectors=15 bits */ | 90 | unsigned char selectors[32768]; /* nSelectors=15 bits */ |
86 | struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ | 91 | struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ |
@@ -91,7 +96,7 @@ struct bunzip_data { | |||
91 | /* Return the next nnn bits of input. All reads from the compressed input | 96 | /* Return the next nnn bits of input. All reads from the compressed input |
92 | are done through this function. All reads are big endian */ | 97 | are done through this function. All reads are big endian */ |
93 | 98 | ||
94 | static unsigned get_bits(bunzip_data *bd, char bits_wanted) | 99 | static unsigned get_bits(bunzip_data *bd, int bits_wanted) |
95 | { | 100 | { |
96 | unsigned bits = 0; | 101 | unsigned bits = 0; |
97 | 102 | ||
@@ -121,7 +126,7 @@ static unsigned get_bits(bunzip_data *bd, char bits_wanted) | |||
121 | 126 | ||
122 | /* Grab next 8 bits of input from buffer. */ | 127 | /* Grab next 8 bits of input from buffer. */ |
123 | 128 | ||
124 | bd->inbufBits = (bd->inbufBits<<8) | bd->inbuf[bd->inbufPos++]; | 129 | bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; |
125 | bd->inbufBitCount += 8; | 130 | bd->inbufBitCount += 8; |
126 | } | 131 | } |
127 | 132 | ||
@@ -205,7 +210,7 @@ static int get_next_block(bunzip_data *bd) | |||
205 | /* Get next value */ | 210 | /* Get next value */ |
206 | 211 | ||
207 | for (j = 0; get_bits(bd, 1); j++) | 212 | for (j = 0; get_bits(bd, 1); j++) |
208 | if (j>=groupCount) return RETVAL_DATA_ERROR; | 213 | if (j >= groupCount) return RETVAL_DATA_ERROR; |
209 | 214 | ||
210 | /* Decode MTF to get the next selector */ | 215 | /* Decode MTF to get the next selector */ |
211 | 216 | ||
@@ -320,19 +325,20 @@ static int get_next_block(bunzip_data *bd) | |||
320 | t += temp[i]; | 325 | t += temp[i]; |
321 | base[i+1] = pp - t; | 326 | base[i+1] = pp - t; |
322 | } | 327 | } |
323 | limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */ | 328 | limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */ |
324 | limit[maxLen] = pp + temp[maxLen] - 1; | 329 | limit[maxLen] = pp + temp[maxLen] - 1; |
325 | base[minLen] = 0; | 330 | base[minLen] = 0; |
326 | } | 331 | } |
327 | 332 | ||
328 | /* We've finished reading and digesting the block header. Now read this | 333 | /* We've finished reading and digesting the block header. Now read this |
329 | block's Huffman coded symbols from the file and undo the Huffman coding | 334 | block's Huffman coded symbols from the file and undo the Huffman coding |
330 | and run length encoding, saving the result into dbuf[dbufCount++]=uc */ | 335 | and run length encoding, saving the result into dbuf[dbufCount++] = uc */ |
331 | 336 | ||
332 | /* Initialize symbol occurrence counters and symbol Move To Front table */ | 337 | /* Initialize symbol occurrence counters and symbol Move To Front table */ |
333 | 338 | ||
339 | memset(byteCount, 0, sizeof(byteCount)); /* smaller, maybe slower? */ | ||
334 | for (i = 0; i < 256; i++) { | 340 | for (i = 0; i < 256; i++) { |
335 | byteCount[i] = 0; | 341 | //byteCount[i] = 0; |
336 | mtfSymbol[i] = (unsigned char)i; | 342 | mtfSymbol[i] = (unsigned char)i; |
337 | } | 343 | } |
338 | 344 | ||
@@ -547,7 +553,7 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
547 | /* If the output buffer is full, snapshot state and return */ | 553 | /* If the output buffer is full, snapshot state and return */ |
548 | 554 | ||
549 | if (gotcount >= len) { | 555 | if (gotcount >= len) { |
550 | bd->writePos =pos; | 556 | bd->writePos = pos; |
551 | bd->writeCurrent = current; | 557 | bd->writeCurrent = current; |
552 | bd->writeCopies++; | 558 | bd->writeCopies++; |
553 | return len; | 559 | return len; |
@@ -573,8 +579,8 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
573 | current = pos & 0xff; | 579 | current = pos & 0xff; |
574 | pos >>= 8; | 580 | pos >>= 8; |
575 | 581 | ||
576 | /* After 3 consecutive copies of the same byte, the 4th is a repeat | 582 | /* After 3 consecutive copies of the same byte, the 4th |
577 | count. We count down from 4 instead | 583 | * is a repeat count. We count down from 4 instead |
578 | * of counting up because testing for non-zero is faster */ | 584 | * of counting up because testing for non-zero is faster */ |
579 | 585 | ||
580 | if (--bd->writeRunCountdown) { | 586 | if (--bd->writeRunCountdown) { |
@@ -606,7 +612,7 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
606 | /* If this block had a CRC error, force file level CRC error. */ | 612 | /* If this block had a CRC error, force file level CRC error. */ |
607 | 613 | ||
608 | if (bd->writeCRC != bd->headerCRC) { | 614 | if (bd->writeCRC != bd->headerCRC) { |
609 | bd->totalCRC = bd->headerCRC+1; | 615 | bd->totalCRC = bd->headerCRC + 1; |
610 | return RETVAL_LAST_BLOCK; | 616 | return RETVAL_LAST_BLOCK; |
611 | } | 617 | } |
612 | } | 618 | } |
@@ -713,8 +719,8 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
713 | for (;;) { | 719 | for (;;) { |
714 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); | 720 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); |
715 | if (i <= 0) break; | 721 | if (i <= 0) break; |
716 | if (i != safe_write(dst_fd, outbuf, i)) { | 722 | if (i != full_write(dst_fd, outbuf, i)) { |
717 | i = RETVAL_UNEXPECTED_OUTPUT_EOF; | 723 | i = RETVAL_SHORT_WRITE; |
718 | break; | 724 | break; |
719 | } | 725 | } |
720 | USE_DESKTOP(total_written += i;) | 726 | USE_DESKTOP(total_written += i;) |
@@ -729,8 +735,8 @@ unpack_bz2_stream(int src_fd, int dst_fd) | |||
729 | } else { | 735 | } else { |
730 | i = RETVAL_OK; | 736 | i = RETVAL_OK; |
731 | } | 737 | } |
732 | } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { | 738 | } else if (i == RETVAL_SHORT_WRITE) { |
733 | bb_error_msg("unexpected EOF"); | 739 | bb_error_msg("short write"); |
734 | } else { | 740 | } else { |
735 | bb_error_msg("bunzip error %d", i); | 741 | bb_error_msg("bunzip error %d", i); |
736 | } | 742 | } |