dentry_extract_skeleton(): Fix bug with DOS name reordering
authorEric Biggers <ebiggers3@gmail.com>
Mon, 2 Sep 2013 14:03:55 +0000 (09:03 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 2 Sep 2013 14:06:06 +0000 (09:06 -0500)
When choosing a different dentry for an inode being extracted, the code didn't
check if it was actually in the tree being extracted.

This bug could cause an infinite loop in extraction backends that required DOS
name reordering and also allowed extracting only a subset of an image---
currently, just the Windows backend.

include/wimlib/dentry.h
src/extract.c

index 2a40ef4..8d359a9 100644 (file)
@@ -159,6 +159,12 @@ struct wim_dentry {
         * characters).  Otherwise this will always be 0. */
        u8 extraction_skipped : 1;
 
+       /* For extraction operations, this flag will be set on dentries in the
+        * tree being extracted.  */
+       u8 in_extraction_tree : 1;
+
+       /* During extraction extractions, this flag will be set after the
+        * "skeleton" of the dentry has been extracted.  */
        u8 skeleton_extracted : 1;
 
        /* When capturing from a NTFS volume using NTFS-3g, this flag is set on
index 115d5ea..ae591bb 100644 (file)
@@ -1143,7 +1143,8 @@ dentry_extract_skeleton(struct wim_dentry *dentry, void *_ctx)
        {
                inode_for_each_dentry(other_dentry, dentry->d_inode) {
                        if (dentry_has_short_name(other_dentry)
-                           && !other_dentry->skeleton_extracted)
+                           && !other_dentry->skeleton_extracted
+                           && other_dentry->in_extraction_tree)
                        {
                                DEBUG("Creating %"TS" before %"TS" "
                                      "to guarantee correct DOS name extraction",
@@ -1623,6 +1624,8 @@ dentry_calculate_extraction_path(struct wim_dentry *dentry, void *_args)
        struct apply_ctx *ctx = _args;
        int ret;
 
+       dentry->in_extraction_tree = 1;
+
        if (dentry == ctx->extract_root || dentry->extraction_skipped)
                return 0;
 
@@ -1742,6 +1745,7 @@ dentry_reset_needs_extraction(struct wim_dentry *dentry, void *_ignore)
 {
        struct wim_inode *inode = dentry->d_inode;
 
+       dentry->in_extraction_tree = 0;
        dentry->extraction_skipped = 0;
        dentry->was_hardlinked = 0;
        dentry->skeleton_extracted = 0;