mirror of
https://git.tukaani.org/xz.git
synced 2026-10-31 03:14:56 +00:00
liblzma: Index decoder: Fix lzma_memusage()
If lzma_stream was initialized using lzma_index_decoder() or lzma_file_info_decoder(), and lzma_memusage() was called after a few Records had already been decoded, the return value was too low because it was calculated based on the number of Records that haven't been decoded yet. So near the end of a big Index, the return value would be tiny compared to the actual memory usage. It worked correctly in the primary use case, that is, after LZMA_MEMLIMIT_ERROR. Thus, in practice this bug didn't matter much.
This commit is contained in:
parent
2187b27c64
commit
bd3bfe8346
@ -28,6 +28,10 @@ typedef struct {
|
|||||||
/// Memory usage limit
|
/// Memory usage limit
|
||||||
uint64_t memlimit;
|
uint64_t memlimit;
|
||||||
|
|
||||||
|
// Memory used for lzma_index once it has been allocated.
|
||||||
|
// Before that, this holds a tiny value.
|
||||||
|
uint64_t memused;
|
||||||
|
|
||||||
/// Target Index
|
/// Target Index
|
||||||
lzma_index *index;
|
lzma_index *index;
|
||||||
|
|
||||||
@ -103,7 +107,13 @@ index_decode(void *coder_ptr, const lzma_allocator *allocator,
|
|||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
|
|
||||||
case SEQ_MEMUSAGE:
|
case SEQ_MEMUSAGE:
|
||||||
if (lzma_index_memusage(1, coder->count) > coder->memlimit) {
|
coder->memused = lzma_index_memusage(1, coder->count);
|
||||||
|
|
||||||
|
// We sanity-checked coder->count in SEQ_COUNT, which
|
||||||
|
// guarantees that lzma_index_memusage() won't fail.
|
||||||
|
assert(coder->memused != UINT64_MAX);
|
||||||
|
|
||||||
|
if (coder->memused > coder->memlimit) {
|
||||||
ret = LZMA_MEMLIMIT_ERROR;
|
ret = LZMA_MEMLIMIT_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -237,7 +247,10 @@ index_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
|
|||||||
{
|
{
|
||||||
lzma_index_coder *coder = coder_ptr;
|
lzma_index_coder *coder = coder_ptr;
|
||||||
|
|
||||||
*memusage = lzma_index_memusage(1, coder->count);
|
// Index decoder is special in sense that the returned memusage
|
||||||
|
// doesn't include the memory usage of the decoder itself; only
|
||||||
|
// the resulting lzma_index is counted.
|
||||||
|
*memusage = coder->memused;
|
||||||
*old_memlimit = coder->memlimit;
|
*old_memlimit = coder->memlimit;
|
||||||
|
|
||||||
if (new_memlimit != 0) {
|
if (new_memlimit != 0) {
|
||||||
@ -270,7 +283,7 @@ index_decoder_reset(lzma_index_coder *coder, const lzma_allocator *allocator,
|
|||||||
// Initialize the rest.
|
// Initialize the rest.
|
||||||
coder->sequence = SEQ_INDICATOR;
|
coder->sequence = SEQ_INDICATOR;
|
||||||
coder->memlimit = my_max(1, memlimit);
|
coder->memlimit = my_max(1, memlimit);
|
||||||
coder->count = 0; // Needs to be initialized due to _memconfig().
|
coder->memused = 1; // If _memconfig() is called before SEQ_MEMUSAGE.
|
||||||
coder->pos = 0;
|
coder->pos = 0;
|
||||||
coder->crc32 = 0;
|
coder->crc32 = 0;
|
||||||
|
|
||||||
@ -368,7 +381,7 @@ lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit,
|
|||||||
} else if (ret == LZMA_MEMLIMIT_ERROR) {
|
} else if (ret == LZMA_MEMLIMIT_ERROR) {
|
||||||
// Tell the caller how much memory would have
|
// Tell the caller how much memory would have
|
||||||
// been needed.
|
// been needed.
|
||||||
*memlimit = lzma_index_memusage(1, coder.count);
|
*memlimit = coder.memused;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user