X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fblob_table.c;h=b3eb63fcad750d17ea7dbe471a543748738a1043;hp=1d87a71761ed219846e5d6395a3f912df83786fa;hb=b82856cb22783df0e19990eb68d3694753f52220;hpb=1fcf9333676be806716535d01b38722ee53d52e9 diff --git a/src/blob_table.c b/src/blob_table.c index 1d87a717..b3eb63fc 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -395,7 +395,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) v = (int)blob1->blob_location - (int)blob2->blob_location; - /* Different resource locations? */ + /* Different locations? */ if (v) return v; @@ -406,7 +406,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) /* Different (possibly split) WIMs? */ if (wim1 != wim2) { - v = memcmp(wim1->hdr.guid, wim2->hdr.guid, WIM_GUID_LEN); + v = cmp_guids(wim1->hdr.guid, wim2->hdr.guid); if (v) return v; } @@ -429,6 +429,10 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) #ifdef __WIN32__ case BLOB_IN_WINNT_FILE_ON_DISK: case BLOB_WIN32_ENCRYPTED: + /* Windows: compare by starting LCN (logical cluster number) */ + v = cmp_u64(blob1->sort_key, blob2->sort_key); + if (v) + return v; #endif /* Compare files by path: just a heuristic that will place files * in the same directory next to each other. */ @@ -607,7 +611,7 @@ do_load_solid_info(WIMStruct *wim, struct wim_resource_descriptor **rdescs, rdesc = rdescs[i]; - wim_res_hdr_to_desc(&reshdr, wim, rdesc); + wim_reshdr_to_desc(&reshdr, wim, rdesc); /* For solid resources, the uncompressed size, compression type, * and chunk size are stored in the resource itself, not in the @@ -852,6 +856,7 @@ read_blob_table(WIMStruct *wim) struct blob_table *table = NULL; struct blob_descriptor *cur_blob = NULL; size_t num_duplicate_blobs = 0; + size_t num_empty_blobs = 0; size_t num_wrong_part_blobs = 0; u32 image_index = 0; struct wim_resource_descriptor **cur_solid_rdescs = NULL; @@ -949,27 +954,13 @@ read_blob_table(WIMStruct *wim) goto out; } - /* How to handle an uncompressed resource with its - * uncompressed size different from its compressed size? - * - * Based on a simple test, WIMGAPI seems to handle this - * as follows: - * - * if (size_in_wim > uncompressed_size) { - * Ignore uncompressed_size; use size_in_wim - * instead. - * } else { - * Honor uncompressed_size, but treat the part of - * the file data above size_in_wim as all zeros. - * } - * - * So we will do the same. */ - if (unlikely(!(reshdr.flags & - WIM_RESHDR_FLAG_COMPRESSED) && - (reshdr.size_in_wim > - reshdr.uncompressed_size))) + if (unlikely(!(reshdr.flags & WIM_RESHDR_FLAG_COMPRESSED) && + (reshdr.size_in_wim != reshdr.uncompressed_size))) { - reshdr.uncompressed_size = reshdr.size_in_wim; + ERROR("Uncompressed resource has " + "size_in_wim != uncompressed_size"); + ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + goto out; } /* Set up a resource descriptor for this blob. */ @@ -978,20 +969,24 @@ read_blob_table(WIMStruct *wim) if (!rdesc) goto oom; - wim_res_hdr_to_desc(&reshdr, wim, rdesc); - - blob_set_is_located_in_nonsolid_wim_resource(cur_blob, rdesc); + wim_reshdr_to_desc_and_blob(&reshdr, wim, rdesc, cur_blob); } /* cur_blob is now a blob bound to a resource. */ /* Ignore entries with all zeroes in the hash field. */ - if (is_zero_hash(cur_blob->hash)) + if (unlikely(is_zero_hash(cur_blob->hash))) goto free_cur_blob_and_continue; + /* Verify that the blob has nonzero size. */ + if (unlikely(cur_blob->size == 0)) { + num_empty_blobs++; + goto free_cur_blob_and_continue; + } + /* Verify that the part number matches that of the underlying * WIM file. */ - if (part_number != wim->hdr.part_number) { + if (unlikely(part_number != wim->hdr.part_number)) { num_wrong_part_blobs++; goto free_cur_blob_and_continue; } @@ -1018,6 +1013,13 @@ read_blob_table(WIMStruct *wim) goto out; } + if (reshdr.flags & WIM_RESHDR_FLAG_SOLID) { + ERROR("Image metadata in solid resources " + "is unsupported."); + ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + goto out; + } + if (wim->hdr.part_number != 1) { WARNING("Ignoring metadata resource found in a " "non-first part of the split WIM"); @@ -1087,6 +1089,9 @@ read_blob_table(WIMStruct *wim) if (num_duplicate_blobs > 0) WARNING("Ignoring %zu duplicate blobs", num_duplicate_blobs); + if (num_empty_blobs > 0) + WARNING("Ignoring %zu empty blobs", num_empty_blobs); + if (num_wrong_part_blobs > 0) { WARNING("Ignoring %zu blobs with wrong part number", num_wrong_part_blobs);