X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=archival%2Flibunarchive%2Fdecompress_bunzip2.c;h=ff7d64d83d8fe41476590c0fb6f90a6bc4210e9b;hb=dcbd51dd2874164b693fc7133a07714c8ea14234;hp=34afd6f99c6c77768e3e223a47a4cecc5b699bdd;hpb=2c98c40ec881dcaac93b069525314bc078359175;p=oweals%2Fbusybox.git diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 34afd6f99..ff7d64d83 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c @@ -1,13 +1,12 @@ /* vi: set sw=4 ts=4: */ -/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). +/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). - Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), - which also acknowledges contributions by Mike Burrows, David Wheeler, - Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, - Robert Sedgewick, and Jon L. Bentley. + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), + which also acknowledges contributions by Mike Burrows, David Wheeler, + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, + Robert Sedgewick, and Jon L. Bentley. - This code is licensed under the LGPLv2: - LGPL http://www.gnu.org/copyleft/lgpl.html + Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ /* @@ -24,40 +23,34 @@ I would ask that anyone benefiting from this work, especially those using it in commercial products, consider making a donation to my local non-profit hospice organization (www.hospiceacadiana.com) in the name of - the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003. + the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003. Manuel */ -#include -#include -#include -#include -#include -#include - #include "libbb.h" +#include "unarchive.h" /* Constants for Huffman coding */ -#define MAX_GROUPS 6 -#define GROUP_SIZE 50 /* 64 would have been more efficient */ -#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ -#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ -#define SYMBOL_RUNA 0 -#define SYMBOL_RUNB 1 +#define MAX_GROUPS 6 +#define GROUP_SIZE 50 /* 64 would have been more efficient */ +#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ +#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ +#define SYMBOL_RUNA 0 +#define SYMBOL_RUNB 1 /* Status return values */ -#define RETVAL_OK 0 -#define RETVAL_LAST_BLOCK (-1) -#define RETVAL_NOT_BZIP_DATA (-2) -#define RETVAL_UNEXPECTED_INPUT_EOF (-3) -#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) -#define RETVAL_DATA_ERROR (-5) -#define RETVAL_OUT_OF_MEMORY (-6) -#define RETVAL_OBSOLETE_INPUT (-7) +#define RETVAL_OK 0 +#define RETVAL_LAST_BLOCK (-1) +#define RETVAL_NOT_BZIP_DATA (-2) +#define RETVAL_UNEXPECTED_INPUT_EOF (-3) +#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) +#define RETVAL_DATA_ERROR (-5) +#define RETVAL_OUT_OF_MEMORY (-6) +#define RETVAL_OBSOLETE_INPUT (-7) /* Other housekeeping constants */ -#define IOBUF_SIZE 4096 +#define IOBUF_SIZE 4096 /* This is what we know about each Huffman coding group */ struct group_data { @@ -82,8 +75,8 @@ typedef struct { /* The CRC values stored in the block header and calculated from the data */ - unsigned int crc32Table[256],headerCRC, totalCRC, writeCRC; - + uint32_t headerCRC, totalCRC, writeCRC; + uint32_t *crc32Table; /* Intermediate buffer and its size (in bytes) */ unsigned int *dbuf, dbufSize; @@ -158,7 +151,7 @@ static int get_next_block(bunzip_data *bd) /* Reset longjmp I/O error handling */ i=setjmp(bd->jmpbuf); - if(i) return i; + if (i) return i; /* Read in header signature and CRC, then validate signature. (last block signature means CRC is for whole file, return now) */ @@ -173,8 +166,8 @@ static int get_next_block(bunzip_data *bd) some code for this in busybox 1.0.0-pre3, but nobody ever noticed that it didn't actually work. */ - if(get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT; - if((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR; + if (get_bits(bd,1)) return RETVAL_OBSOLETE_INPUT; + if ((origPtr=get_bits(bd,24)) > dbufSize) return RETVAL_DATA_ERROR; /* mapping table: if some byte values are never used (encoding things like ascii text), the compression code removes the gaps to have fewer @@ -187,7 +180,7 @@ static int get_next_block(bunzip_data *bd) for (i=0;i<16;i++) { if(t&(1<<(15-i))) { k=get_bits(bd,16); - for(j=0;j<16;j++) + for (j=0;j<16;j++) if(k&(1<<(15-j))) symToByte[symTotal++]=(16*i)+j; } } @@ -203,17 +196,17 @@ static int get_next_block(bunzip_data *bd) start of the list.) */ if(!(nSelectors=get_bits(bd, 15))) return RETVAL_DATA_ERROR; - for(i=0; i=groupCount) return RETVAL_DATA_ERROR; + for (j=0;get_bits(bd,1);j++) if (j>=groupCount) return RETVAL_DATA_ERROR; /* Decode MTF to get the next selector */ uc = mtfSymbol[j]; - for(;j;j--) mtfSymbol[j] = mtfSymbol[j-1]; + for (;j;j--) mtfSymbol[j] = mtfSymbol[j-1]; mtfSymbol[0]=selectors[i]=uc; } @@ -234,7 +227,7 @@ static int get_next_block(bunzip_data *bd) t=get_bits(bd, 5)-1; for (i = 0; i < symCount; i++) { - for(;;) { + for (;;) { if (((unsigned)t) > (MAX_HUFCODE_BITS-1)) return RETVAL_DATA_ERROR; @@ -261,7 +254,7 @@ static int get_next_block(bunzip_data *bd) /* Find largest and smallest lengths in this group */ minLen=maxLen=length[0]; - for(i = 1; i < symCount; i++) { + for (i = 1; i < symCount; i++) { if(length[i] > maxLen) maxLen = length[i]; else if(length[i] < minLen) minLen = length[i]; } @@ -291,9 +284,9 @@ static int get_next_block(bunzip_data *bd) /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ pp=0; - for(i=minLen;i<=maxLen;i++) { + for (i=minLen;i<=maxLen;i++) { temp[i]=limit[i]=0; - for(t=0;tpermute[pp++] = t; } @@ -332,7 +325,7 @@ static int get_next_block(bunzip_data *bd) /* Initialize symbol occurrence counters and symbol Move To Front table */ - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { byteCount[i] = 0; mtfSymbol[i]=(unsigned char)i; } @@ -340,7 +333,7 @@ static int get_next_block(bunzip_data *bd) /* Loop through compressed symbols. */ runPos=dbufCount=selector=0; - for(;;) { + for (;;) { /* fetch next Huffman coding group from list. */ @@ -379,7 +372,7 @@ got_huff_bits: /* Figure how how many bits are in next symbol and unget extras */ i=hufGroup->minLen; - while(j>limit[i]) ++i; + while (j>limit[i]) ++i; bd->inbufBitCount += (hufGroup->maxLen - i); /* Huffman decode value to get nextSym (with bounds checking) */ @@ -413,7 +406,7 @@ got_huff_bits: context). Thus space is saved. */ t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ - runPos <<= 1; + if(runPos < dbufSize) runPos <<= 1; goto end_of_huffman_loop; } @@ -428,7 +421,7 @@ got_huff_bits: uc = symToByte[mtfSymbol[0]]; byteCount[uc] += t; - while(t--) dbuf[dbufCount++]=uc; + while (t--) dbuf[dbufCount++]=uc; } /* Is this the terminating symbol? */ @@ -480,7 +473,7 @@ end_of_huffman_loop: /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ j=0; - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { k=j+byteCount[i]; byteCount[i] = j; j=k; @@ -542,7 +535,7 @@ static int read_bunzip(bunzip_data *bd, char *outbuf, int len) /* Loop outputting bytes */ - for(;;) { + for (;;) { /* If the output buffer is full, snapshot state and return */ @@ -618,7 +611,7 @@ decode_next_byte: bd->writeCount=previous; return (previous!=RETVAL_LAST_BLOCK) ? previous : gotcount; } - bd->writeCRC=0xffffffffUL; + bd->writeCRC=~0; pos=bd->writePos; current=bd->writeCurrent; goto decode_next_byte; @@ -632,7 +625,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, int len) { bunzip_data *bd; - unsigned int i,j,c; + unsigned int i; const unsigned int BZh0=(((unsigned int)'B')<<24)+(((unsigned int)'Z')<<16) +(((unsigned int)'h')<<8)+(unsigned int)'0'; @@ -643,8 +636,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, /* Allocate bunzip_data. Most fields initialize to zero. */ - bd=*bdp=xmalloc(i); - memset(bd,0,sizeof(bunzip_data)); + bd=*bdp=xzalloc(i); /* Setup input buffer */ @@ -655,12 +647,7 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, /* Init the CRC32 table (big endian) */ - for(i=0;i<256;i++) { - c=i<<24; - for(j=8;j;j--) - c=c&0x80000000 ? (c<<1)^0x04c11db7 : (c<<1); - bd->crc32Table[i]=c; - } + bd->crc32Table = crc32_filltable(1); /* Setup for I/O error handling via longjmp */ @@ -684,20 +671,24 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, /* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data, not end of file.) */ -extern int uncompressStream(int src_fd, int dst_fd) +USE_DESKTOP(long long) int +uncompressStream(int src_fd, int dst_fd) { + USE_DESKTOP(long long total_written = 0;) char *outbuf; bunzip_data *bd; int i; outbuf=xmalloc(IOBUF_SIZE); - if(!(i=start_bunzip(&bd,src_fd,0,0))) { - for(;;) { + i=start_bunzip(&bd,src_fd,0,0); + if(!i) { + for (;;) { if((i=read_bunzip(bd,outbuf,IOBUF_SIZE)) <= 0) break; if(i!=write(dst_fd,outbuf,i)) { i=RETVAL_UNEXPECTED_OUTPUT_EOF; break; } + USE_DESKTOP(total_written += i;) } } @@ -705,27 +696,27 @@ extern int uncompressStream(int src_fd, int dst_fd) if(i==RETVAL_LAST_BLOCK) { if (bd->headerCRC!=bd->totalCRC) { - bb_error_msg("Data integrity error when decompressing."); + bb_error_msg("data integrity error when decompressing"); } else { i=RETVAL_OK; } } else if (i==RETVAL_UNEXPECTED_OUTPUT_EOF) { - bb_error_msg("Compressed file ends unexpectedly"); + bb_error_msg("compressed file ends unexpectedly"); } else { - bb_error_msg("Decompression failed"); + bb_error_msg("decompression failed"); } - if(bd->dbuf) free(bd->dbuf); + free(bd->dbuf); free(bd); free(outbuf); - return i; + return i ? i : USE_DESKTOP(total_written) + 0; } #ifdef TESTING static char * const bunzip_errors[]={NULL,"Bad file checksum","Not bzip data", "Unexpected input EOF","Unexpected output EOF","Data error", - "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."}; + "Out of memory","Obsolete (pre 0.9.5) bzip format not supported."}; /* Dumb little test thing, decompress stdin to stdout */ int main(int argc, char *argv[]) @@ -733,8 +724,8 @@ int main(int argc, char *argv[]) int i=uncompressStream(0,1); char c; - if(i) fprintf(stderr,"%s\n", bunzip_errors[-i]); - else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n"); + if(i<0) fprintf(stderr,"%s\n", bunzip_errors[-i]); + else if(read(0,&c,1)) fprintf(stderr,"Trailing garbage ignored\n"); return -i; } #endif