Fix data corruption in LZMA2 decoder.

This commit is contained in:
Lasse Collin 2008-12-15 10:01:59 +02:00
parent 1ceebcf7e1
commit ff7fb2c605
3 changed files with 32 additions and 8 deletions

View File

@ -58,6 +58,17 @@ struct lzma_coder_s {
};
static void
lz_decoder_reset(lzma_coder *coder)
{
coder->dict.pos = 0;
coder->dict.full = 0;
coder->dict.buf[coder->dict.size - 1] = '\0';
coder->dict.need_reset = false;
return;
}
static lzma_ret
decode_buffer(lzma_coder *coder,
const uint8_t *restrict in, size_t *restrict in_pos,
@ -93,6 +104,10 @@ decode_buffer(lzma_coder *coder,
copy_size);
*out_pos += copy_size;
// Reset the dictionary if so requested by process().
if (coder->dict.need_reset)
lz_decoder_reset(coder);
// Return if everything got decoded or an error occurred, or
// if there's no more data to decode.
if (ret != LZMA_OK || *out_pos == out_size
@ -235,7 +250,7 @@ lzma_lz_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
next->coder->dict.size = dict_size;
}
dict_reset(&next->coder->dict);
lz_decoder_reset(next->coder);
// Miscellaneous initializations
next->coder->next_finished = false;

View File

@ -45,6 +45,9 @@ typedef struct {
/// Size of the dictionary
size_t size;
/// True when dictionary should be reset before decoding more data.
bool need_reset;
} lzma_dict;
@ -224,9 +227,8 @@ dict_write(lzma_dict *restrict dict, const uint8_t *restrict in,
static inline void
dict_reset(lzma_dict *dict)
{
dict->pos = 0;
dict->full = 0;
dict->buf[dict->size - 1] = '\0';
dict->need_reset = true;
return;
}
#endif

View File

@ -74,12 +74,11 @@ lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict,
const uint32_t control = in[*in_pos];
++*in_pos;
// Dictionary reset implies that next LZMA chunk has to set
// new properties.
if (control >= 0xE0 || control == 1) {
dict_reset(dict);
coder->need_dictionary_reset = false;
// Dictionary reset implies that next LZMA chunk has
// to set new properties.
coder->need_properties = true;
coder->need_dictionary_reset = true;
} else if (coder->need_dictionary_reset) {
return LZMA_DATA_ERROR;
}
@ -125,6 +124,14 @@ lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict,
coder->next_sequence = SEQ_COPY;
}
if (coder->need_dictionary_reset) {
// Finish the dictionary reset and let the caller
// flush the dictionary to the actual output buffer.
coder->need_dictionary_reset = false;
dict_reset(dict);
return LZMA_OK;
}
break;
}