From 79b64b516e5bdb486832f88788362dbe9deb1b61 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 28 Oct 2012 00:47:15 -0500 Subject: [PATCH] Metadata resource compatibility For compatibility with 7zip, do not write any extra random bytes to the end of the metadata resources. This means that without adding some other source of random output, adding identical images will result in identical metadata resources. This is still allowed, but for compatibility with ImageX, lookup table entries are duplicated rather than shared. --- src/lookup_table.c | 9 ++++++++- src/resource.c | 25 +++++++++---------------- src/write.c | 5 ++++- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/lookup_table.c b/src/lookup_table.c index 142e7e04..3d66ca18 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -332,8 +332,15 @@ int read_lookup_table(WIMStruct *w) goto out_free_cur_entry; } + /* Ordinarily, no two streams should share the same SHA1 message + * digest. However, this constraint can be broken for metadata + * resources--- two identical images will have the same metadata + * resource, but their lookup table entries are not shared. */ duplicate_entry = __lookup_resource(table, cur_entry->hash); - if (duplicate_entry) { + if (duplicate_entry + && !((duplicate_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) + && cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)) + { ERROR("The WIM lookup table contains two entries with the " "same SHA1 message digest!"); ERROR("The first entry is:"); diff --git a/src/resource.c b/src/resource.c index 013f9ec5..4832030c 100644 --- a/src/resource.c +++ b/src/resource.c @@ -1288,7 +1288,6 @@ int write_metadata_resource(WIMStruct *w) struct lookup_table_entry *lte; u64 metadata_original_size; const struct wim_security_data *sd; - const unsigned random_tail_len = 20; DEBUG("Writing metadata resource for image %d", w->current_image); @@ -1314,7 +1313,7 @@ int write_metadata_resource(WIMStruct *w) calculate_subdir_offsets(root, &subdir_offset); /* Total length of the metadata resource (uncompressed) */ - metadata_original_size = subdir_offset + random_tail_len; + metadata_original_size = subdir_offset; /* Allocate a buffer to contain the uncompressed metadata resource */ buf = MALLOC(metadata_original_size); @@ -1330,18 +1329,9 @@ int write_metadata_resource(WIMStruct *w) /* Write the dentry tree into the resource buffer */ p = write_dentry_tree(root, p); - /* - * Append 20 random bytes to the metadata resource so that we don't have - * identical metadata resources if we happen to append exactly the same - * image twice without any changes in timestamps. If this were to - * happen, it would cause confusion about the number and order of images - * in the WIM. - */ - randomize_byte_array(p, random_tail_len); - /* We MUST have exactly filled the buffer; otherwise we calculated its * size incorrectly or wrote the data incorrectly. */ - wimlib_assert(p - buf + random_tail_len == metadata_original_size); + wimlib_assert(p - buf == metadata_original_size); /* Get the lookup table entry for the metadata resource so we can update * it. */ @@ -1362,14 +1352,17 @@ int write_metadata_resource(WIMStruct *w) /* It's very likely the SHA1 message digest of the metadata resource * changed, so re-insert the lookup table entry into the lookup table. + * + * We do not check for other lookup table entries having the same SHA1 + * message digest. It's possible for 2 absolutely identical images to + * be added, therefore causing 2 identical metadata resources to be in + * the WIM. However, in this case, it's expected for 2 separate lookup + * table entries to be created, even though this doesn't make a whole + * lot of sense since they will share the same SHA1 message digest. * */ lookup_table_unlink(w->lookup_table, lte); lookup_table_insert(w->lookup_table, lte); - /* We do not allow a metadata resource to be referenced multiple times, - * and the 20 random bytes appended to it should make it extremely - * likely for each metadata resource to be unique, even if the exact - * same image is captured. */ wimlib_assert(lte->out_refcnt == 0); lte->out_refcnt = 1; diff --git a/src/write.c b/src/write.c index fd61ae1d..7c4d985c 100644 --- a/src/write.c +++ b/src/write.c @@ -85,6 +85,8 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags) ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES, write_flags); if (ret != 0) { ERROR("Failed to write the WIM file `%s'", tmpfile); + if (unlink(tmpfile) != 0) + WARNING("Failed to remove `%s'", tmpfile); return ret; } @@ -485,10 +487,11 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path, ret = for_image(w, image, write_metadata_resource); if (ret != 0) { - ERROR("Failed to write WIM image metadata to `%s'", path); + /*ERROR("Failed to write WIM image metadata to `%s'", path);*/ goto out; } + ret = finish_write(w, image, write_flags); out: -- 2.43.0