]> wimlib.net Git - wimlib/blobdiff - src/lookup_table.c
new_lookup_table_entry() fix
[wimlib] / src / lookup_table.c
index 0c6a55fcccb9463c8092fda7269ef09b048745a8..c491f076e23c682c473ce5e0c824ac51c0796887 100644 (file)
@@ -52,7 +52,7 @@ err:
        return NULL;
 }
 
-struct lookup_table_entry *new_lookup_table_entry(WIMStruct *wim)
+struct lookup_table_entry *new_lookup_table_entry()
 {
        struct lookup_table_entry *lte;
        
@@ -66,7 +66,6 @@ struct lookup_table_entry *new_lookup_table_entry(WIMStruct *wim)
 
        lte->part_number  = 1;
        lte->refcnt       = 1;
-       lte->wim          = wim;
        INIT_LIST_HEAD(&lte->lte_group_list);
        return lte;
 }
@@ -197,7 +196,7 @@ int read_lookup_table(WIMStruct *w)
 
        while (num_entries--) {
                const u8 *p;
-               struct lookup_table_entry *cur_entry;
+               struct lookup_table_entry *cur_entry, *duplicate_entry;
 
                if (fread(buf, 1, sizeof(buf), w->fp) != sizeof(buf)) {
                        if (feof(w->fp)) {
@@ -209,7 +208,7 @@ int read_lookup_table(WIMStruct *w)
                        ret = WIMLIB_ERR_READ;
                        goto out;
                }
-               cur_entry = new_lookup_table_entry(w);
+               cur_entry = new_lookup_table_entry();
                if (!cur_entry) {
                        ret = WIMLIB_ERR_NOMEM;
                        goto out;
@@ -221,7 +220,31 @@ int read_lookup_table(WIMStruct *w)
                p = get_u16(p, &cur_entry->part_number);
                p = get_u32(p, &cur_entry->refcnt);
                p = get_bytes(p, SHA1_HASH_SIZE, cur_entry->hash);
+
+               duplicate_entry = __lookup_resource(table, cur_entry->hash);
+               if (duplicate_entry) {
+                       ERROR("The WIM lookup table contains two entries with the "
+                             "same SHA1 message digest!");
+                       ERROR("The first entry is:");
+                       print_lookup_table_entry(duplicate_entry);
+                       ERROR("The second entry is:");
+                       print_lookup_table_entry(cur_entry);
+                       ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       goto out;
+               }
                lookup_table_insert(table, cur_entry);
+
+               if (!(cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
+                   && (cur_entry->resource_entry.size !=
+                     cur_entry->resource_entry.original_size))
+               {
+                       ERROR("Found uncompressed resource with original size "
+                             "not the same as compressed size");
+                       ERROR("The lookup table entry for the resource is as follows:");
+                       print_lookup_table_entry(cur_entry);
+                       ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       goto out;
+               }
        }
        DEBUG("Done reading lookup table.");
        w->lookup_table = table;
@@ -369,7 +392,20 @@ int lookup_resource(WIMStruct *w, const char *path,
        struct dentry *dentry;
        struct lookup_table_entry *lte;
        unsigned stream_idx;
+       const char *stream_name;
+       char *p = NULL;
+
+       if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
+               stream_name = path_stream_name(path);
+               if (stream_name) {
+                       p = (char*)stream_name - 1;
+                       *p = '\0';
+               }
+       }
+
        dentry = get_dentry(w, path);
+       if (p)
+               *p = ':';
        if (!dentry)
                return -ENOENT;
 
@@ -380,22 +416,19 @@ int lookup_resource(WIMStruct *w, const char *path,
              && dentry_is_directory(dentry))
                return -EISDIR;
        stream_idx = 0;
-       if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
-               const char *stream_name = path_stream_name(path);
-               if (stream_name) {
-                       size_t stream_name_len = strlen(stream_name);
-                       for (u16 i = 0; i < dentry->num_ads; i++) {
-                               if (ads_entry_has_name(&dentry->ads_entries[i],
-                                                      stream_name,
-                                                      stream_name_len))
-                               {
-                                       stream_idx = i + 1;
-                                       lte = dentry->ads_entries[i].lte;
-                                       goto out;
-                               }
+       if (stream_name) {
+               size_t stream_name_len = strlen(stream_name);
+               for (u16 i = 0; i < dentry->num_ads; i++) {
+                       if (ads_entry_has_name(&dentry->ads_entries[i],
+                                              stream_name,
+                                              stream_name_len))
+                       {
+                               stream_idx = i + 1;
+                               lte = dentry->ads_entries[i].lte;
+                               goto out;
                        }
-                       return -ENOENT;
                }
+               return -ENOENT;
        }
 out:
        if (dentry_ret)