bunzip2: make proper fix for the problem "fixed" in rev. 22521 Thanks for Rob Landley
No binary (build failed)
—
(log yok)
| @@ -66,7 +66,6 @@ struct group_data { | |
| * | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER | |
| * and moved it (inbufBitCount) to offset 0. | |
| */ | |
| - | |
| struct bunzip_data { | |
| /* I/O tracking data (file handles, buffers, positions, etc.) */ | |
| unsigned inbufBitCount, inbufBits; | |
| @@ -102,11 +101,9 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |
| /* If we need to get more data from the byte buffer, do so. (Loop getting | |
| one byte at a time to enforce endianness and avoid unaligned access.) */ | |
| - | |
| while ((int)(bd->inbufBitCount) < bits_wanted) { | |
| /* If we need to read more data from file into byte buffer, do so */ | |
| - | |
| if (bd->inbufPos == bd->inbufCount) { | |
| /* if "no input fd" case: in_fd == -1, read fails, we jump */ | |
| bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); | |
| @@ -116,7 +113,6 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |
| } | |
| /* Avoid 32-bit overflow (dump bit buffer to top of output) */ | |
| - | |
| if (bd->inbufBitCount >= 24) { | |
| bits = bd->inbufBits & ((1 << bd->inbufBitCount) - 1); | |
| bits_wanted -= bd->inbufBitCount; | |
| @@ -125,13 +121,11 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |
| } | |
| /* Grab next 8 bits of input from buffer. */ | |
| - | |
| bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++]; | |
| bd->inbufBitCount += 8; | |
| } | |
| /* Calculate result */ | |
| - | |
| bd->inbufBitCount -= bits_wanted; | |
| bits |= (bd->inbufBits >> bd->inbufBitCount) & ((1 << bits_wanted) - 1); | |
| @@ -139,29 +133,24 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |
| } | |
| /* Unpacks the next block and sets up for the inverse burrows-wheeler step. */ | |
| - | |
| static int get_next_block(bunzip_data *bd) | |
| { | |
| struct group_data *hufGroup; | |
| - | int dbufCount, nextSym, dbufSize, groupCount, *base, selector, |
| + | int dbufCount, nextSym, dbufSize, groupCount, *base, *limit, selector, |
| i, j, k, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; | |
| unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; | |
| - | /* limit was int* but was changed to unsigned* - grep for '[x]' |
| - | * in comment to see where it is important. -- vda */ |
| - | unsigned *dbuf, *limit, origPtr; |
| + | unsigned *dbuf, origPtr; |
| dbuf = bd->dbuf; | |
| dbufSize = bd->dbufSize; | |
| selectors = bd->selectors; | |
| /* Reset longjmp I/O error handling */ | |
| - | |
| i = setjmp(bd->jmpbuf); | |
| if (i) return i; | |
| /* Read in header signature and CRC, then validate signature. | |
| (last block signature means CRC is for whole file, return now) */ | |
| - | |
| i = get_bits(bd, 24); | |
| j = get_bits(bd, 24); | |
| bd->headerCRC = get_bits(bd, 32); | |
| @@ -171,7 +160,6 @@ static int get_next_block(bunzip_data *bd) | |
| /* We can add support for blockRandomised if anybody complains. There was | |
| 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; | |
| origPtr = get_bits(bd, 24); | |
| if ((int)origPtr > dbufSize) return RETVAL_DATA_ERROR; | |
| @@ -181,7 +169,6 @@ static int get_next_block(bunzip_data *bd) | |
| symbols to deal with, and writes a sparse bitfield indicating which | |
| values were present. We make a translation table to convert the symbols | |
| back to the corresponding bytes. */ | |
| - | |
| t = get_bits(bd, 16); | |
| symTotal = 0; | |
| for (i = 0; i < 16; i++) { | |
| @@ -194,7 +181,6 @@ static int get_next_block(bunzip_data *bd) | |
| } | |
| /* How many different Huffman coding groups does this block use? */ | |
| - | |
| groupCount = get_bits(bd, 3); | |
| if (groupCount < 2 || groupCount > MAX_GROUPS) | |
| return RETVAL_DATA_ERROR; | |
| @@ -203,19 +189,16 @@ static int get_next_block(bunzip_data *bd) | |
| group. Read in the group selector list, which is stored as MTF encoded | |
| bit runs. (MTF=Move To Front, as each value is used it's moved to the | |
| start of the list.) */ | |
| - | |
| nSelectors = get_bits(bd, 15); | |
| if (!nSelectors) return RETVAL_DATA_ERROR; | |
| for (i = 0; i < groupCount; i++) mtfSymbol[i] = i; | |
| for (i = 0; i < nSelectors; i++) { | |
| /* Get next value */ | |
| - | |
| 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]; | |
| mtfSymbol[0] = selectors[i] = uc; | |
| @@ -223,10 +206,11 @@ static int get_next_block(bunzip_data *bd) | |
| /* Read the Huffman coding tables for each group, which code for symTotal | |
| literal symbols, plus two run symbols (RUNA, RUNB) */ | |
| - | |
| symCount = symTotal + 2; | |
| for (j = 0; j < groupCount; j++) { | |
| - | unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; |
| + | unsigned char length[MAX_SYMBOLS]; |
| + | /* 8 bits is ALMOST enough for temp[], see below */ |
| + | unsigned temp[MAX_HUFCODE_BITS+1]; |
| int minLen, maxLen, pp; | |
| /* Read Huffman code lengths for each symbol. They're stored in | |
| @@ -235,7 +219,6 @@ static int get_next_block(bunzip_data *bd) | |
| (Subtracting 1 before the loop and then adding it back at the end is | |
| an optimization that makes the test inside the loop simpler: symbol | |
| length 0 becomes negative, so an unsigned inequality catches it.) */ | |
| - | |
| t = get_bits(bd, 5) - 1; | |
| for (i = 0; i < symCount; i++) { | |
| for (;;) { | |
| @@ -245,7 +228,6 @@ static int get_next_block(bunzip_data *bd) | |
| /* If first bit is 0, stop. Else second bit indicates whether | |
| to increment or decrement the value. Optimization: grab 2 | |
| bits and unget the second if the first was 0. */ | |
| - | |
| k = get_bits(bd, 2); | |
| if (k < 2) { | |
| bd->inbufBitCount++; | |
| @@ -253,17 +235,14 @@ static int get_next_block(bunzip_data *bd) | |
| } | |
| /* Add one if second bit 1, else subtract 1. Avoids if/else */ | |
| - | |
| t += (((k+1) & 2) - 1); | |
| } | |
| /* Correct for the initial -1, to get the final symbol length */ | |
| - | |
| length[i] = t + 1; | |
| } | |
| /* Find largest and smallest lengths in this group */ | |
| - | |
| minLen = maxLen = length[0]; | |
| for (i = 1; i < symCount; i++) { | |
| if (length[i] > maxLen) maxLen = length[i]; | |
| @@ -280,7 +259,6 @@ static int get_next_block(bunzip_data *bd) | |
| * number of bits can have. This is how the Huffman codes can vary in | |
| * length: each code with a value>limit[length] needs another bit. | |
| */ | |
| - | |
| hufGroup = bd->groups + j; | |
| hufGroup->minLen = minLen; | |
| hufGroup->maxLen = maxLen; | |
| @@ -288,12 +266,10 @@ static int get_next_block(bunzip_data *bd) | |
| /* Note that minLen can't be smaller than 1, so we adjust the base | |
| and limit array pointers so we're not always wasting the first | |
| entry. We do this again when using them (during symbol decoding).*/ | |
| - | |
| base = hufGroup->base - 1; | |
| - | limit = (unsigned*)hufGroup->limit - 1; |
| + | limit = hufGroup->limit - 1; |
| /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ | |
| - | |
| pp = 0; | |
| for (i = minLen; i <= maxLen; i++) { | |
| temp[i] = limit[i] = 0; | |
| @@ -303,14 +279,14 @@ static int get_next_block(bunzip_data *bd) | |
| } | |
| /* Count symbols coded for at each bit length */ | |
| - | |
| + | /* NB: in pathological cases, temp[8] can end ip being 256. |
| + | * That's why uint8_t is too small for temp[]. */ |
| for (i = 0; i < symCount; i++) temp[length[i]]++; | |
| /* Calculate limit[] (the largest symbol-coding value at each bit | |
| * length, which is (previous limit<<1)+symbols at this level), and | |
| * base[] (number of symbols to ignore at each bit length, which is | |
| * limit minus the cumulative count of symbols coded for already). */ | |
| - | |
| pp = t = 0; | |
| for (i = minLen; i < maxLen; i++) { | |
| pp += temp[i]; | |
| @@ -321,14 +297,12 @@ static int get_next_block(bunzip_data *bd) | |
| each level we're really only interested in the first few bits, | |
| so here we set all the trailing to-be-ignored bits to 1 so they | |
| don't affect the value>limit[length] comparison. */ | |
| - | |
| limit[i] = (pp << (maxLen - i)) - 1; | |
| pp <<= 1; | |
| t += temp[i]; | |
| base[i+1] = pp - t; | |
| } | |
| limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */ | |
| - | /* [x] was observed to occasionally have -1 here: -- vda */ |
| limit[maxLen] = pp + temp[maxLen] - 1; | |
| base[minLen] = 0; | |
| } | |
| @@ -338,7 +312,6 @@ static int get_next_block(bunzip_data *bd) | |
| and run length encoding, saving the result into dbuf[dbufCount++] = uc */ | |
| /* Initialize symbol occurrence counters and symbol Move To Front table */ | |
| - | |
| memset(byteCount, 0, sizeof(byteCount)); /* smaller, maybe slower? */ | |
| for (i = 0; i < 256; i++) { | |
| //byteCount[i] = 0; | |
| @@ -350,13 +323,12 @@ static int get_next_block(bunzip_data *bd) | |
| runPos = dbufCount = selector = 0; | |
| for (;;) { | |
| - | /* fetch next Huffman coding group from list. */ |
| - | |
| + | /* Fetch next Huffman coding group from list. */ |
| symCount = GROUP_SIZE - 1; | |
| if (selector >= nSelectors) return RETVAL_DATA_ERROR; | |
| hufGroup = bd->groups + selectors[selector++]; | |
| base = hufGroup->base - 1; | |
| - | limit = (unsigned*)hufGroup->limit - 1; |
| + | limit = hufGroup->limit - 1; |
| continue_this_group: | |
| /* Read next Huffman-coded symbol. */ | |
| @@ -370,7 +342,6 @@ static int get_next_block(bunzip_data *bd) | |
| dry). The following (up to got_huff_bits:) is equivalent to | |
| j = get_bits(bd, hufGroup->maxLen); | |
| */ | |
| - | |
| while ((int)(bd->inbufBitCount) < hufGroup->maxLen) { | |
| if (bd->inbufPos == bd->inbufCount) { | |
| j = get_bits(bd, hufGroup->maxLen); | |
| @@ -385,13 +356,11 @@ static int get_next_block(bunzip_data *bd) | |
| got_huff_bits: | |
| /* Figure how how many bits are in next symbol and unget extras */ | |
| - | |
| i = hufGroup->minLen; | |
| - | while ((unsigned)j > limit[i]) ++i; |
| + | while (j > limit[i]) ++i; |
| bd->inbufBitCount += (hufGroup->maxLen - i); | |
| /* Huffman decode value to get nextSym (with bounds checking) */ | |
| - | |
| if (i > hufGroup->maxLen) | |
| return RETVAL_DATA_ERROR; | |
| j = (j >> (hufGroup->maxLen - i)) - base[i]; | |
| @@ -403,11 +372,9 @@ static int get_next_block(bunzip_data *bd) | |
| byte, or a repeated run of the most recent literal byte. First, | |
| check if nextSym indicates a repeated run, and if so loop collecting | |
| how many times to repeat the last literal. */ | |
| - | |
| if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */ | |
| /* If this is the start of a new run, zero out counter */ | |
| - | |
| if (!runPos) { | |
| runPos = 1; | |
| t = 0; | |
| @@ -420,7 +387,6 @@ static int get_next_block(bunzip_data *bd) | |
| the basic or 0/1 method (except all bits 0, which would use no | |
| symbols, but a run of length 0 doesn't mean anything in this | |
| context). Thus space is saved. */ | |
| - | |
| t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */ | |
| if (runPos < dbufSize) runPos <<= 1; | |
| goto end_of_huffman_loop; | |
| @@ -430,7 +396,6 @@ static int get_next_block(bunzip_data *bd) | |
| how many times to repeat the last literal, so append that many | |
| copies to our buffer of decoded symbols (dbuf) now. (The last | |
| literal used is the one at the head of the mtfSymbol array.) */ | |
| - | |
| if (runPos) { | |
| runPos = 0; | |
| if (dbufCount + t >= dbufSize) return RETVAL_DATA_ERROR; | |
| @@ -441,7 +406,6 @@ static int get_next_block(bunzip_data *bd) | |
| } | |
| /* Is this the terminating symbol? */ | |
| - | |
| if (nextSym > symTotal) break; | |
| /* At this point, nextSym indicates a new literal character. Subtract | |
| @@ -451,7 +415,6 @@ static int get_next_block(bunzip_data *bd) | |
| first symbol in the mtf array, position 0, would have been handled | |
| as part of a run above. Therefore 1 unused mtf position minus | |
| 2 non-literal nextSym values equals -1.) */ | |
| - | |
| if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR; | |
| i = nextSym - 1; | |
| uc = mtfSymbol[i]; | |
| @@ -460,7 +423,6 @@ static int get_next_block(bunzip_data *bd) | |
| * small number of symbols, and are bound by 256 in any case, using | |
| * memmove here would typically be bigger and slower due to function | |
| * call overhead and other assorted setup costs. */ | |
| - | |
| do { | |
| mtfSymbol[i] = mtfSymbol[i-1]; | |
| } while (--i); | |
| @@ -468,13 +430,11 @@ static int get_next_block(bunzip_data *bd) | |
| uc = symToByte[uc]; | |
| /* We have our literal byte. Save it into dbuf. */ | |
| - | |
| byteCount[uc]++; | |
| dbuf[dbufCount++] = (unsigned)uc; | |
| /* Skip group initialization if we're not done with this group. Done | |
| * this way to avoid compiler warning. */ | |
| - | |
| end_of_huffman_loop: | |
| if (symCount--) goto continue_this_group; | |
| } | |
| @@ -487,7 +447,6 @@ static int get_next_block(bunzip_data *bd) | |
| */ | |
| /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ | |
| - | |
| j = 0; | |
| for (i = 0; i < 256; i++) { | |
| k = j + byteCount[i]; | |
| @@ -496,7 +455,6 @@ static int get_next_block(bunzip_data *bd) | |
| } | |
| /* Figure out what order dbuf would be in if we sorted it. */ | |
| - | |
| for (i = 0; i < dbufCount; i++) { | |
| uc = (unsigned char)(dbuf[i] & 0xff); | |
| dbuf[byteCount[uc]] |= (i << 8); | |
| @@ -506,7 +464,6 @@ static int get_next_block(bunzip_data *bd) | |
| /* Decode first byte by hand to initialize "previous" byte. Note that it | |
| doesn't get output, and if the first three characters are identical | |
| it doesn't qualify as a run (hence writeRunCountdown=5). */ | |
| - | |
| if (dbufCount) { | |
| if ((int)origPtr >= dbufCount) return RETVAL_DATA_ERROR; | |
| bd->writePos = dbuf[origPtr]; | |
| @@ -525,7 +482,6 @@ static int get_next_block(bunzip_data *bd) | |
| error (all errors are negative numbers). If out_fd!=-1, outbuf and len | |
| are ignored, data is written to out_fd and return is RETVAL_OK or error. | |
| */ | |
| - | |
| int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| { | |
| const unsigned *dbuf; | |
| @@ -542,19 +498,15 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| /* We will always have pending decoded data to write into the output | |
| buffer unless this is the very first call (in which case we haven't | |
| Huffman-decoded a block into the intermediate buffer yet). */ | |
| - | |
| if (bd->writeCopies) { | |
| /* Inside the loop, writeCopies means extra copies (beyond 1) */ | |
| - | |
| --bd->writeCopies; | |
| /* Loop outputting bytes */ | |
| - | |
| for (;;) { | |
| /* If the output buffer is full, snapshot state and return */ | |
| - | |
| if (gotcount >= len) { | |
| bd->writePos = pos; | |
| bd->writeCurrent = current; | |
| @@ -563,13 +515,11 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| } | |
| /* Write next byte into output buffer, updating CRC */ | |
| - | |
| outbuf[gotcount++] = current; | |
| bd->writeCRC = (bd->writeCRC << 8) | |
| - | ^ bd->crc32Table[(bd->writeCRC >> 24) ^ current]; |
| + | ^ bd->crc32Table[(bd->writeCRC >> 24) ^ current]; |
| /* Loop now if we're outputting multiple copies of this byte */ | |
| - | |
| if (bd->writeCopies) { | |
| --bd->writeCopies; | |
| continue; | |
| @@ -585,35 +535,29 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| /* After 3 consecutive copies of the same byte, the 4th | |
| * is a repeat count. We count down from 4 instead | |
| * of counting up because testing for non-zero is faster */ | |
| - | |
| if (--bd->writeRunCountdown) { | |
| if (current != previous) | |
| bd->writeRunCountdown = 4; | |
| } else { | |
| /* We have a repeated run, this byte indicates the count */ | |
| - | |
| bd->writeCopies = current; | |
| current = previous; | |
| bd->writeRunCountdown = 5; | |
| /* Sometimes there are just 3 bytes (run length 0) */ | |
| - | |
| if (!bd->writeCopies) goto decode_next_byte; | |
| /* Subtract the 1 copy we'd output anyway to get extras */ | |
| - | |
| --bd->writeCopies; | |
| } | |
| } | |
| /* Decompression of this block completed successfully */ | |
| - | |
| bd->writeCRC = ~bd->writeCRC; | |
| bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bd->writeCRC; | |
| /* If this block had a CRC error, force file level CRC error. */ | |
| - | |
| if (bd->writeCRC != bd->headerCRC) { | |
| bd->totalCRC = bd->headerCRC + 1; | |
| return RETVAL_LAST_BLOCK; | |
| @@ -622,7 +566,6 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| /* Refill the intermediate buffer by Huffman-decoding next block of input */ | |
| /* (previous is just a convenient unused temp variable here) */ | |
| - | |
| previous = get_next_block(bd); | |
| if (previous) { | |
| bd->writeCount = previous; | |
| @@ -634,7 +577,6 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| goto decode_next_byte; | |
| } | |
| - | |
| /* Allocate the structure, read file header. If in_fd==-1, inbuf must contain | |
| a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are | |
| ignored, and data is read from file handle into temporary buffer. */ | |
| @@ -642,7 +584,6 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |
| /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() | |
| should work for NOFORK applets too, we must be extremely careful to not leak | |
| any allocations! */ | |
| - | |
| int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf, | |
| int len) | |
| { | |
| @@ -653,16 +594,13 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in | |
| }; | |
| /* Figure out how much data to allocate */ | |
| - | |
| i = sizeof(bunzip_data); | |
| if (in_fd != -1) i += IOBUF_SIZE; | |
| /* Allocate bunzip_data. Most fields initialize to zero. */ | |
| - | |
| bd = *bdp = xzalloc(i); | |
| /* Setup input buffer */ | |
| - | |
| bd->in_fd = in_fd; | |
| if (-1 == in_fd) { | |
| /* in this case, bd->inbuf is read-only */ | |
| @@ -672,22 +610,18 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in | |
| bd->inbuf = (unsigned char *)(bd + 1); | |
| /* Init the CRC32 table (big endian) */ | |
| - | |
| crc32_filltable(bd->crc32Table, 1); | |
| /* Setup for I/O error handling via longjmp */ | |
| - | |
| i = setjmp(bd->jmpbuf); | |
| if (i) return i; | |
| /* Ensure that file starts with "BZh['1'-'9']." */ | |
| - | |
| i = get_bits(bd, 32); | |
| if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA; | |
| - | /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of |
| + | /* Fourth byte (ascii '1'-'9') indicates block size in units of 100k of |
| uncompressed data. Allocate intermediate buffer for block. */ | |
| - | |
| bd->dbufSize = 100000 * (i - BZh0); | |
| /* Cannot use xmalloc - may leak bd in NOFORK case! */ | |
| @@ -707,7 +641,6 @@ void FAST_FUNC dealloc_bunzip(bunzip_data *bd) | |
| /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ | |
| - | |
| USE_DESKTOP(long long) int FAST_FUNC | |
| unpack_bz2_stream(int src_fd, int dst_fd) | |
| { | |