Fixed bug when capturing NTFS file with multiple named data streams
authorEric Biggers <ebiggers3@gmail.com>
Sun, 2 Sep 2012 21:12:21 +0000 (16:12 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 2 Sep 2012 21:12:21 +0000 (16:12 -0500)
NEWS
README
configure.ac
src/dentry.c

diff --git a/NEWS b/NEWS
index dc3f218fc556fe9da45cbfdd60632d9758ae31ff..731560847743c5f818295d1d8778bd80e5b01baa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 Only the most important changes more recent than version 0.6 are noted here.
 
+Version 1.0.2:
+       Fixed bug when capturing NTFS file with multiple named data streams
+
 Version 1.0.1:
        Fixed problem when exporting images from XPRESS to LZX compressed WIM or
        vice versa
diff --git a/README b/README
index 2fa925e981eaa548b4d547b773f262ffaacfe04b..8e6d401a9b08e70521d984ff73e9ea80a6ec7ed3 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
                                   WIMLIB                                    
 
-This is wimlib version 1.0.1 (September 2012).  wimlib can be used to read,
+This is wimlib version 1.0.2 (September 2012).  wimlib can be used to read,
 write, and mount files in the Windows Imaging Format (WIM files).  These
 files are normally created by using the `imagex.exe' utility on Windows,
 but this library provides a free implementation of imagex for UNIX-based
index 24952332ba032c4d09384a39c3af87d3a253db66..d761ec8196f1f7e565868871c80e1279ebbc0fe5 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([wimlib], [1.0.1], [ebiggers3@gmail.com])
+AC_INIT([wimlib], [1.0.2], [ebiggers3@gmail.com])
 AC_CONFIG_SRCDIR([src/wim.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_AUX_DIR([build-aux])
index 116efa58c0711cf9ce61dcfccf0391b43b6182b9..1f0fd86c7e047a4121757ed12c84318aa21e99c6 100644 (file)
@@ -173,17 +173,45 @@ struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
        }
        num_ads = dentry->num_ads + 1;
        ads_entries = REALLOC(dentry->ads_entries,
-                             num_ads * sizeof(struct ads_entry));
+                             num_ads * sizeof(dentry->ads_entries[0]));
        if (!ads_entries) {
                ERROR("Failed to allocate memory for new alternate data stream");
                return NULL;
        }
+       wimlib_assert(ads_entries == dentry->ads_entries ||
+                       ads_entries < dentry->ads_entries ||
+                       ads_entries > dentry->ads_entries + dentry->num_ads);
        if (ads_entries != dentry->ads_entries) {
                /* We moved the ADS entries.  Adjust the stream lists. */
                for (u16 i = 0; i < dentry->num_ads; i++) {
                        struct list_head *cur = &ads_entries[i].lte_group_list.list;
-                       cur->prev->next = cur;
-                       cur->next->prev = cur;
+                       struct list_head *prev = cur->prev;
+                       struct list_head *next = cur->next;
+                       if ((u8*)prev >= (u8*)dentry->ads_entries
+                           && (u8*)prev < (u8*)(dentry->ads_entries + dentry->num_ads)) {
+                               /* Previous entry was located in the same ads_entries
+                                * array!  Adjust our own prev pointer. */
+                               u16 idx = (struct ads_entry*)prev -
+                                           (struct ads_entry*)&dentry->ads_entries[0].lte_group_list.list;
+                               cur->prev = &ads_entries[idx].lte_group_list.list;
+                       } else {
+                               /* Previous entry is located in a different ads_entries
+                                * array.  Adjust its next pointer. */
+                               prev->next = cur;
+                       }
+                       next = cur->next;
+                       if ((u8*)next >= (u8*)dentry->ads_entries
+                           && (u8*)next < (u8*)(dentry->ads_entries + dentry->num_ads)) {
+                               /* Next entry was located in the same ads_entries array!
+                                * Adjust our own next pointer. */
+                               u16 idx = (struct ads_entry*)next -
+                                           (struct ads_entry*)&dentry->ads_entries[0].lte_group_list.list;
+                               cur->next = &ads_entries[idx].lte_group_list.list;
+                       } else {
+                               /* Next entry is located in a different ads_entries
+                                * array.  Adjust its prev pointer. */
+                               next->prev = cur;
+                       }
                }
        }
 
@@ -595,6 +623,7 @@ struct dentry *new_dentry(const char *name)
        dentry->prev   = dentry;
        dentry->parent = dentry;
        INIT_LIST_HEAD(&dentry->link_group_list);
+       INIT_LIST_HEAD(&dentry->lte_group_list.list);
        return dentry;
 err:
        FREE(dentry);