From d4b9c90b4979c07c049b06be709187a60c17112b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 2 Sep 2012 16:12:21 -0500 Subject: [PATCH] Fixed bug when capturing NTFS file with multiple named data streams --- NEWS | 3 +++ README | 2 +- configure.ac | 2 +- src/dentry.c | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 37 insertions(+), 5 deletions(-) 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); -- 2.43.0