]> wimlib.net Git - wimlib/blobdiff - src/extract.c
extract_trees(): Correctly destroy stream list in error path
[wimlib] / src / extract.c
index ee82be2bf1e5df21f1adb86c97d60e81b63ec620..9cbac117f54438d25372c90cb43dd4df4c327bb5 100644 (file)
@@ -1658,17 +1658,11 @@ dentry_reset_extraction_list_node(struct wim_dentry *dentry)
        dentry->extraction_list = (struct list_head){NULL, NULL};
 }
 
-static void
-dentry_delete_from_list(struct wim_dentry *dentry)
+static int
+dentry_delete_from_list(struct wim_dentry *dentry, void *_ignore)
 {
        list_del(&dentry->extraction_list);
        dentry_reset_extraction_list_node(dentry);
-}
-
-static int
-do_dentry_delete_from_list(struct wim_dentry *dentry, void *_ignore)
-{
-       dentry_delete_from_list(dentry);
        return 0;
 }
 
@@ -1885,7 +1879,7 @@ out_replace:
        return 0;
 
 skip_dentry:
-       for_dentry_in_tree(dentry, do_dentry_delete_from_list, NULL);
+       for_dentry_in_tree(dentry, dentry_delete_from_list, NULL);
        return 0;
 }
 
@@ -1907,8 +1901,8 @@ dentry_list_calculate_extraction_names(struct list_head *dentry_list,
        struct list_head *prev, *cur;
 
        /* Can't use list_for_each_entry() because a call to
-        * dentry_calculate_extraction_name() may the current dentry and its
-        * children from the list.  */
+        * dentry_calculate_extraction_name() may delete the current dentry and
+        * its children from the list.  */
 
        prev = dentry_list;
        for (;;) {
@@ -2490,7 +2484,7 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
         * volume.  */
        ret = ctx.ops->start_extract(target, &ctx);
        if (ret)
-               return ret;
+               goto out_destroy_dentry_list;
 
        /* Get and check the features required to extract the dentries.  */
        dentry_list_get_features(&dentry_list, &required_features);
@@ -2506,12 +2500,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
         * can't be extracted due to naming problems.  */
        ret = dentry_list_calculate_extraction_names(&dentry_list, &ctx);
        if (ret)
-               goto out_destroy_dentry_list;
+               goto out_finish_or_abort_extract;
 
        /* Build list of streams to extract.  */
        ret = dentry_list_resolve_streams(&dentry_list, &ctx);
        if (ret)
-               goto out_destroy_dentry_list;
+               goto out_finish_or_abort_extract;
        INIT_LIST_HEAD(&ctx.stream_list);
        ret = dentry_list_ref_streams(&dentry_list, &ctx);
        if (ret)
@@ -2677,8 +2671,6 @@ out_free_realtarget:
 out_destroy_stream_list:
        if (!(ctx.extract_flags & WIMLIB_EXTRACT_FLAG_FILE_ORDER))
                destroy_stream_list(&ctx.stream_list);
-out_destroy_dentry_list:
-       destroy_dentry_list(&dentry_list);
 out_finish_or_abort_extract:
        if (ret) {
                if (ctx.ops->abort_extract)
@@ -2687,6 +2679,8 @@ out_finish_or_abort_extract:
                if (ctx.ops->finish_extract)
                        ret = ctx.ops->finish_extract(&ctx);
        }
+out_destroy_dentry_list:
+       destroy_dentry_list(&dentry_list);
        return ret;
 }