mirror of https://git.tukaani.org/xz.git
Index decoder fixes.
The Index decoder code didn't perfectly match the API docs, which said that *i will be set to point to the decoded Index only after decoding has succeeded. The docs were a bit unclear too. Now the decoder will initially set *i to NULL. *i will be set to point to the decoded Index once decoding has succeeded. This simplifies applications too, since it avoids dangling pointers.
This commit is contained in:
parent
465d1b0d65
commit
1f19690914
|
@ -317,12 +317,13 @@ extern LZMA_API(lzma_ret) lzma_index_encoder(lzma_stream *strm, lzma_index *i)
|
||||||
* \brief Initialize .xz Index decoder
|
* \brief Initialize .xz Index decoder
|
||||||
*
|
*
|
||||||
* \param strm Pointer to properly prepared lzma_stream
|
* \param strm Pointer to properly prepared lzma_stream
|
||||||
* \param i Pointer to a pointer that will be made to point
|
* \param i The decoded Index will be made available via
|
||||||
* to the final decoded Index once lzma_code() has
|
* this pointer. Initially this function will
|
||||||
* returned LZMA_STREAM_END. That is,
|
* set *i to NULL (the old value is ignored). If
|
||||||
* lzma_index_decoder() always takes care of
|
* decoding succeeds (lzma_code() returns
|
||||||
* allocating a new lzma_index structure, and *i
|
* LZMA_STREAM_END), *i will be set to point
|
||||||
* doesn't need to be initialized by the caller.
|
* to the decoded Index, which the application
|
||||||
|
* has to later free with lzma_index_end().
|
||||||
* \param memlimit How much memory the resulting Index is allowed
|
* \param memlimit How much memory the resulting Index is allowed
|
||||||
* to require.
|
* to require.
|
||||||
*
|
*
|
||||||
|
@ -373,11 +374,11 @@ extern LZMA_API(lzma_ret) lzma_index_buffer_encode(lzma_index *i,
|
||||||
/**
|
/**
|
||||||
* \brief Single-call .xz Index decoder
|
* \brief Single-call .xz Index decoder
|
||||||
*
|
*
|
||||||
* \param i Pointer to a pointer that will be made to point
|
* \param i If decoding succeeds, *i will point to the
|
||||||
* to the final decoded Index if decoding is
|
* decoded Index, which the application has to
|
||||||
* successful. That is, lzma_index_buffer_decode()
|
* later free with lzma_index_end(). If an error
|
||||||
* always takes care of allocating a new
|
* occurs, *i will be NULL. The old value of *i
|
||||||
* lzma_index structure, and *i doesn't need to be
|
* is always ignored and thus doesn't need to be
|
||||||
* initialized by the caller.
|
* initialized by the caller.
|
||||||
* \param memlimit Pointer to how much memory the resulting Index
|
* \param memlimit Pointer to how much memory the resulting Index
|
||||||
* is allowed to require. The value pointed by
|
* is allowed to require. The value pointed by
|
||||||
|
|
|
@ -32,6 +32,10 @@ struct lzma_coder_s {
|
||||||
/// Target Index
|
/// Target Index
|
||||||
lzma_index *index;
|
lzma_index *index;
|
||||||
|
|
||||||
|
/// Pointer give by the application, which is set after
|
||||||
|
/// successful decoding.
|
||||||
|
lzma_index **index_ptr;
|
||||||
|
|
||||||
/// Number of Records left to decode.
|
/// Number of Records left to decode.
|
||||||
lzma_vli count;
|
lzma_vli count;
|
||||||
|
|
||||||
|
@ -174,6 +178,10 @@ index_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||||
|
|
||||||
} while (++coder->pos < 4);
|
} while (++coder->pos < 4);
|
||||||
|
|
||||||
|
// Decoding was successful, now we can let the application
|
||||||
|
// see the decoded Index.
|
||||||
|
*coder->index_ptr = coder->index;
|
||||||
|
|
||||||
// Make index NULL so we don't free it unintentionally.
|
// Make index NULL so we don't free it unintentionally.
|
||||||
coder->index = NULL;
|
coder->index = NULL;
|
||||||
|
|
||||||
|
@ -222,15 +230,21 @@ static lzma_ret
|
||||||
index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
|
index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
|
||||||
lzma_index **i, uint64_t memlimit)
|
lzma_index **i, uint64_t memlimit)
|
||||||
{
|
{
|
||||||
|
// Remember the pointer given by the application. We will set it
|
||||||
|
// to point to the decoded Index only if decoding is successful.
|
||||||
|
// Before that, keep it NULL so that applications can always safely
|
||||||
|
// pass it to lzma_index_end() no matter did decoding succeed or not.
|
||||||
|
coder->index_ptr = i;
|
||||||
|
*i = NULL;
|
||||||
|
|
||||||
// We always allocate a new lzma_index.
|
// We always allocate a new lzma_index.
|
||||||
*i = lzma_index_init(NULL, allocator);
|
coder->index = lzma_index_init(NULL, allocator);
|
||||||
if (*i == NULL)
|
if (coder->index == NULL)
|
||||||
return LZMA_MEM_ERROR;
|
return LZMA_MEM_ERROR;
|
||||||
|
|
||||||
// Initialize the rest.
|
// Initialize the rest.
|
||||||
coder->sequence = SEQ_INDICATOR;
|
coder->sequence = SEQ_INDICATOR;
|
||||||
coder->memlimit = memlimit;
|
coder->memlimit = memlimit;
|
||||||
coder->index = *i;
|
|
||||||
coder->count = 0; // Needs to be initialized due to _memconfig().
|
coder->count = 0; // Needs to be initialized due to _memconfig().
|
||||||
coder->pos = 0;
|
coder->pos = 0;
|
||||||
coder->crc32 = 0;
|
coder->crc32 = 0;
|
||||||
|
@ -282,7 +296,8 @@ lzma_index_buffer_decode(
|
||||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||||
{
|
{
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (i == NULL || in == NULL || in_pos == NULL || *in_pos > in_size)
|
if (i == NULL || memlimit == NULL
|
||||||
|
|| in == NULL || in_pos == NULL || *in_pos > in_size)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
||||||
// Initialize the decoder.
|
// Initialize the decoder.
|
||||||
|
@ -302,8 +317,7 @@ lzma_index_buffer_decode(
|
||||||
} else {
|
} else {
|
||||||
// Something went wrong, free the Index structure and restore
|
// Something went wrong, free the Index structure and restore
|
||||||
// the input position.
|
// the input position.
|
||||||
lzma_index_end(*i, allocator);
|
lzma_index_end(coder.index, allocator);
|
||||||
*i = NULL;
|
|
||||||
*in_pos = in_start;
|
*in_pos = in_start;
|
||||||
|
|
||||||
if (ret == LZMA_OK) {
|
if (ret == LZMA_OK) {
|
||||||
|
|
Loading…
Reference in New Issue