mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
More fixes to LZMA decoder's flush marker handling.
This commit is contained in:
parent
f73c2ab607
commit
3599dba957
1 changed files with 30 additions and 22 deletions
|
@ -425,13 +425,7 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
// Not a repeated match
|
||||
//
|
||||
// We will decode a new distance and store
|
||||
// the value to rep0.
|
||||
|
||||
// The latest three match distances are kept in
|
||||
// memory in case there are repeated matches.
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
// the value to distance.
|
||||
|
||||
// Decode the length of the match.
|
||||
length_decode(len, coder->len_decoder, pos_state);
|
||||
|
@ -447,36 +441,36 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
if (pos_slot >= START_POS_MODEL_INDEX) {
|
||||
uint32_t direct_bits = (pos_slot >> 1) - 1;
|
||||
assert(direct_bits >= 1 && direct_bits <= 30);
|
||||
rep0 = 2 | (pos_slot & 1);
|
||||
uint32_t distance = 2 | (pos_slot & 1);
|
||||
|
||||
if (pos_slot < END_POS_MODEL_INDEX) {
|
||||
assert(direct_bits <= 5);
|
||||
rep0 <<= direct_bits;
|
||||
assert(rep0 <= 96);
|
||||
distance <<= direct_bits;
|
||||
assert(distance <= 96);
|
||||
// -1 is fine, because
|
||||
// bittree_reverse_decode()
|
||||
// starts from table index [1]
|
||||
// (not [0]).
|
||||
assert((int32_t)(rep0 - pos_slot - 1) >= -1);
|
||||
assert((int32_t)(rep0 - pos_slot - 1) <= 82);
|
||||
// We add the result to rep0, so rep0
|
||||
assert((int32_t)(distance - pos_slot - 1) >= -1);
|
||||
assert((int32_t)(distance - pos_slot - 1) <= 82);
|
||||
// We add the result to distance, so distance
|
||||
// must not be part of second argument
|
||||
// of the macro.
|
||||
const int32_t offset = rep0 - pos_slot - 1;
|
||||
bittree_reverse_decode(rep0, coder->pos_decoders + offset,
|
||||
const int32_t offset = distance - pos_slot - 1;
|
||||
bittree_reverse_decode(distance, coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
} else {
|
||||
assert(pos_slot >= 14);
|
||||
assert(direct_bits >= 6);
|
||||
direct_bits -= ALIGN_BITS;
|
||||
assert(direct_bits >= 2);
|
||||
rc_decode_direct(rep0, direct_bits);
|
||||
rep0 <<= ALIGN_BITS;
|
||||
rc_decode_direct(distance, direct_bits);
|
||||
distance <<= ALIGN_BITS;
|
||||
|
||||
bittree_reverse_decode(rep0, coder->pos_align_decoder,
|
||||
bittree_reverse_decode(distance, coder->pos_align_decoder,
|
||||
ALIGN_BITS);
|
||||
|
||||
if (rep0 == UINT32_MAX) {
|
||||
if (distance == UINT32_MAX) {
|
||||
if (len == LEN_SPECIAL_EOPM) {
|
||||
// End of Payload Marker found.
|
||||
coder->lz.eopm_detected = true;
|
||||
|
@ -501,16 +495,31 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
rc_reset(rc);
|
||||
|
||||
// If we don't have enough input here, we jump
|
||||
// out of the loop without calling rc_normalize().
|
||||
// out of the loop. Note that while there is a
|
||||
// useless call to rc_normalize(), it does nothing
|
||||
// since we have just reset the range decoder.
|
||||
if (!rc_read_init(&rc, in, &in_pos_local, in_size))
|
||||
goto out;
|
||||
break;
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The latest three match distances are kept in
|
||||
// memory in case there are repeated matches.
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
|
||||
} else {
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = pos_slot;
|
||||
}
|
||||
|
||||
|
@ -630,7 +639,6 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
|||
// Update the *data structure. //
|
||||
/////////////////////////////////
|
||||
|
||||
out:
|
||||
// Range decoder
|
||||
rc_from_local(coder->rc);
|
||||
|
||||
|
|
Loading…
Reference in a new issue