liblzma: Fix a memory leak in error path of lzma_index_dup().

lzma_index_dup() calls index_dup_stream() which, in case of
an error, calls index_stream_end() to free memory allocated
by index_stream_init(). However, it illogically didn't
actually free the memory. To make it logical, the tree
handling code was modified a bit in addition to changing
index_stream_end().

Thanks to Evan Nemerson for the bug report.
This commit is contained in:
Lasse Collin 2015-10-12 20:29:09 +03:00
parent 7f05803979
commit 3bf857edfe
1 changed files with 9 additions and 9 deletions

View File

@ -202,22 +202,21 @@ index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator,
if (node->right != NULL) if (node->right != NULL)
index_tree_node_end(node->right, allocator, free_func); index_tree_node_end(node->right, allocator, free_func);
if (free_func != NULL) free_func(node, allocator);
free_func(node, allocator);
lzma_free(node, allocator);
return; return;
} }
/// Free the meory allocated for a tree. If free_func is not NULL, /// Free the memory allocated for a tree. Each node is freed using the
/// it is called on each node before freeing the node. This is used /// given free_func which is either &lzma_free or &index_stream_end.
/// to free the Record groups from each index_stream before freeing /// The latter is used to free the Record groups from each index_stream
/// the index_stream itself. /// before freeing the index_stream itself.
static void static void
index_tree_end(index_tree *tree, const lzma_allocator *allocator, index_tree_end(index_tree *tree, const lzma_allocator *allocator,
void (*free_func)(void *node, const lzma_allocator *allocator)) void (*free_func)(void *node, const lzma_allocator *allocator))
{ {
assert(free_func != NULL);
if (tree->root != NULL) if (tree->root != NULL)
index_tree_node_end(tree->root, allocator, free_func); index_tree_node_end(tree->root, allocator, free_func);
@ -371,7 +370,8 @@ static void
index_stream_end(void *node, const lzma_allocator *allocator) index_stream_end(void *node, const lzma_allocator *allocator)
{ {
index_stream *s = node; index_stream *s = node;
index_tree_end(&s->groups, allocator, NULL); index_tree_end(&s->groups, allocator, &lzma_free);
lzma_free(s, allocator);
return; return;
} }