aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2011-05-27 22:25:44 +0300
committerLasse Collin <lasse.collin@tukaani.org>2011-05-28 09:44:12 +0300
commit6c4d4db2bc8d8b682bd927144d37daa2ab21a6d6 (patch)
treeb56cbc12405938435f21216915e0e5a0baea5f81 /src
parentliblzma: Handle allocation failures correctly in lzma_index_init(). (diff)
downloadxz-6c4d4db2bc8d8b682bd927144d37daa2ab21a6d6.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 '')
-rw-r--r--src/xz/list.c21
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;
}