]> granicus.if.org Git - xz/commitdiff
liblzma: Fix a memory leak in error path of lzma_index_dup().
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 12 Oct 2015 17:29:09 +0000 (20:29 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Mon, 26 Dec 2016 15:57:51 +0000 (17:57 +0200)
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.

src/liblzma/common/index.c

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