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 dc3f218..7315608 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 2fa925e..8e6d401 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 2495233..d761ec8 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 116efa5..1f0fd86 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);