From: Eric Biggers Date: Sun, 2 Sep 2012 21:12:21 +0000 (-0500) Subject: Fixed bug when capturing NTFS file with multiple named data streams X-Git-Tag: v1.0.2~16 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=d4b9c90b4979c07c049b06be709187a60c17112b;hp=35fe5c7c2f2e5054abd93a7b755c2c670ee476da Fixed bug when capturing NTFS file with multiple named data streams --- diff --git a/NEWS b/NEWS index dc3f218f..73156084 100644 --- 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 2fa925e9..8e6d401a 100644 --- 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 diff --git a/configure.ac b/configure.ac index 24952332..d761ec81 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/dentry.c b/src/dentry.c index 116efa58..1f0fd86c 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -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);