X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fblob_table.c;h=386155031c264ab87f799228966002db836d85cd;hb=b143910f8f18f0725adaf4af7e0bbe7ac5ab5382;hp=5d464a979d5ed0ac2f9c71b734600746c238586f;hpb=8b676e7d340fb8197824745eb387e1d3154e6f60;p=wimlib diff --git a/src/blob_table.c b/src/blob_table.c index 5d464a97..38615503 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2012, 2013, 2014, 2015 Eric Biggers + * Copyright (C) 2012-2016 Eric Biggers * * This file is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -22,7 +22,7 @@ * details. * * You should have received a copy of the GNU Lesser General Public License - * along with this file; if not, see http://www.gnu.org/licenses/. + * along with this file; if not, see https://www.gnu.org/licenses/. */ #ifdef HAVE_CONFIG_H @@ -36,6 +36,7 @@ #include "wimlib/assert.h" #include "wimlib/bitops.h" #include "wimlib/blob_table.h" +#include "wimlib/dentry.h" #include "wimlib/encoding.h" #include "wimlib/endianness.h" #include "wimlib/error.h" @@ -54,21 +55,13 @@ struct blob_table { size_t mask; /* capacity - 1; capacity is a power of 2 */ }; -static size_t -next_power_of_2(size_t n) -{ - if (n <= 1) - return 1; - return (size_t)1 << (1 + flsw(n - 1)); -} - struct blob_table * new_blob_table(size_t capacity) { struct blob_table *table; struct hlist_head *array; - capacity = next_power_of_2(capacity); + capacity = roundup_pow_of_2(capacity); table = MALLOC(sizeof(struct blob_table)); if (table == NULL) @@ -139,7 +132,7 @@ clone_blob_descriptor(const struct blob_descriptor *old) if (new->file_on_disk == NULL) goto out_free; break; -#ifdef __WIN32__ +#ifdef _WIN32 case BLOB_IN_WINDOWS_FILE: new->windows_file = clone_windows_file(old->windows_file); break; @@ -191,7 +184,7 @@ blob_release_location(struct blob_descriptor *blob) (void*)&blob->attached_buffer); FREE(blob->file_on_disk); break; -#ifdef __WIN32__ +#ifdef _WIN32 case BLOB_IN_WINDOWS_FILE: free_windows_file(blob->windows_file); break; @@ -469,7 +462,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) /* Compare files by path: just a heuristic that will place files * in the same directory next to each other. */ return tstrcmp(blob1->file_on_disk, blob2->file_on_disk); -#ifdef __WIN32__ +#ifdef _WIN32 case BLOB_IN_WINDOWS_FILE: return cmp_windows_files(blob1->windows_file, blob2->windows_file); #endif @@ -592,7 +585,7 @@ struct blob_descriptor_disk { /* SHA-1 message digest of the uncompressed data of this blob, or all * zeroes if this blob is of zero length. */ u8 hash[SHA1_HASH_SIZE]; -} _packed_attribute; +} __attribute__((packed)); /* Given a nonempty run of consecutive blob descriptors with the SOLID flag set, * count how many specify resources (as opposed to blobs within those @@ -908,7 +901,7 @@ read_blob_table(WIMStruct *wim) if (!table) goto oom; - /* Allocate and initalize blob descriptors from the raw blob table + /* Allocate and initialize blob descriptors from the raw blob table * buffer. */ for (size_t i = 0; i < num_entries; i++) { const struct blob_descriptor_disk *disk_entry = @@ -1015,9 +1008,6 @@ read_blob_table(WIMStruct *wim) } if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) { - - cur_blob->is_metadata = 1; - /* Blob table entry for a metadata resource. */ /* Metadata entries with no references must be ignored. @@ -1064,7 +1054,10 @@ read_blob_table(WIMStruct *wim) * this overrides the actual locations of the metadata * resources themselves in the WIM file as well as any * information written in the XML data. */ - wim->image_metadata[image_index++]->metadata_blob = cur_blob; + wim->image_metadata[image_index] = new_unloaded_image_metadata(cur_blob); + if (!wim->image_metadata[image_index]) + goto oom; + image_index++; } else { /* Blob table entry for a non-metadata blob. */ @@ -1099,8 +1092,6 @@ read_blob_table(WIMStruct *wim) if (wim->hdr.part_number == 1 && image_index != wim->hdr.image_count) { WARNING("Could not find metadata resources for all images"); - for (u32 i = image_index; i < wim->hdr.image_count; i++) - put_image_metadata(wim->image_metadata[i], NULL); wim->hdr.image_count = image_index; } @@ -1245,7 +1236,7 @@ new_blob_from_data_buffer(const void *buffer, size_t size, struct blob_descriptor *blob; void *buffer_copy; - sha1_buffer(buffer, size, hash); + sha1(buffer, size, hash); blob = lookup_blob(blob_table, hash); if (blob) @@ -1269,7 +1260,7 @@ new_blob_from_data_buffer(const void *buffer, size_t size, struct blob_descriptor * after_blob_hashed(struct blob_descriptor *blob, struct blob_descriptor **back_ptr, - struct blob_table *blob_table) + struct blob_table *blob_table, struct wim_inode *inode) { struct blob_descriptor *duplicate_blob; @@ -1283,7 +1274,16 @@ after_blob_hashed(struct blob_descriptor *blob, * this blob to the duplicate and update the reference to this * blob (from a stream) to point to the duplicate. The caller * is responsible for freeing @blob if needed. */ - wimlib_assert(duplicate_blob->size == blob->size); + if (duplicate_blob->size != blob->size) { + tchar hash_str[SHA1_HASH_STRING_LEN]; + + sprint_hash(blob->hash, hash_str); + WARNING("SHA-1 collision at \"%"TS"\"\n" + " (hash=%"TS", size=%"PRIu64", other_size=%"PRIu64").\n" + " File will be corrupted!", + inode_any_full_path(inode), hash_str, + blob->size, duplicate_blob->size); + } duplicate_blob->refcnt += blob->refcnt; blob->refcnt = 0; *back_ptr = duplicate_blob; @@ -1317,15 +1317,17 @@ hash_unhashed_blob(struct blob_descriptor *blob, struct blob_table *blob_table, struct blob_descriptor **blob_ret) { struct blob_descriptor **back_ptr; + struct wim_inode *inode; int ret; back_ptr = retrieve_pointer_to_unhashed_blob(blob); + inode = blob->back_inode; ret = sha1_blob(blob); if (ret) return ret; - *blob_ret = after_blob_hashed(blob, back_ptr, blob_table); + *blob_ret = after_blob_hashed(blob, back_ptr, blob_table, inode); return 0; }