diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2011-05-27 22:25:44 +0300 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2011-05-27 22:25:44 +0300 |
commit | c0297445064951807803457dca1611b3c47e7f0f (patch) | |
tree | da3b5a93bbcdffd06b185bb5b978cd68fffe9949 /src | |
parent | liblzma: Handle allocation failures correctly in lzma_index_init(). (diff) | |
download | xz-c0297445064951807803457dca1611b3c47e7f0f.tar.xz |
xz: Fix error handling in xz -lvv.
It could do an invalid free() and read past the end
of the uninitialized filters array.
Diffstat (limited to 'src')
-rw-r--r-- | src/xz/list.c | 21 |
1 files changed, 6 insertions, 15 deletions
diff --git a/src/xz/list.c b/src/xz/list.c index 1c93718b..98307eb2 100644 --- a/src/xz/list.c +++ b/src/xz/list.c @@ -382,14 +382,9 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter, if (buf.u8[0] == 0) goto data_error; - lzma_block block; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - - // Initialize the pointers so that they can be passed to free(). - for (size_t i = 0; i < ARRAY_SIZE(filters); ++i) - filters[i].options = NULL; - // Initialize the block structure and decode Block Header Size. + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_block block; block.version = 0; block.check = iter->stream.flags->check; block.filters = filters; @@ -437,6 +432,10 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter, break; case LZMA_DATA_ERROR: + // Free the memory allocated by lzma_block_header_decode(). + for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) + free(filters[i].options); + goto data_error; default: @@ -466,14 +465,6 @@ data_error: // Show the error message. message_error("%s: %s", pair->src_name, message_strm(LZMA_DATA_ERROR)); - - // Free the memory allocated by lzma_block_header_decode(). - // This is truly needed only if we get here after a succcessful - // call to lzma_block_header_decode() but it doesn't hurt to - // always do it. - for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) - free(filters[i].options); - return true; } |