]> wimlib.net Git - wimlib/blobdiff - src/metadata_resource.c
w -> wim
[wimlib] / src / metadata_resource.c
index 5b22ab6dd378a2503e4b728b7d4c87fc527eccb5..37206d6743f3d77c20edcdb8fef6acab51389810 100644 (file)
@@ -41,7 +41,7 @@
  * end-of-directory is signaled by a directory entry of length '0', really of
  * length 8, because that's how long the 'length' field is.
  *
- * @w:         Pointer to the WIMStruct for the WIM file.
+ * @wim:               Pointer to the WIMStruct for the WIM file.
  *
  * @imd:       Pointer to the image metadata structure for the image whose
  *             metadata resource we are reading.  Its `metadata_lte' member
@@ -59,7 +59,9 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
        struct wim_dentry *root;
        const struct wim_lookup_table_entry *metadata_lte;
        u64 metadata_len;
+       u8 hash[SHA1_HASH_SIZE];
        struct wim_security_data *security_data;
+       struct wim_inode *inode;
 
        metadata_lte = imd->metadata_lte;
        metadata_len = wim_resource_size(metadata_lte);
@@ -100,6 +102,13 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
        if (ret)
                goto out_free_buf;
 
+       sha1_buffer(buf, metadata_len, hash);
+       if (!hashes_equal(metadata_lte->hash, hash)) {
+               ERROR("Metadata resource is corrupted (invalid SHA-1 message digest)!");
+               ret = WIMLIB_ERR_INVALID_RESOURCE_HASH;
+               goto out_free_buf;
+       }
+
        DEBUG("Finished reading metadata resource into memory.");
 
        /* The root directory entry starts after security data, aligned on an
@@ -131,8 +140,11 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
                          security_data->total_length, root);
 
        if (ret == 0 && root->length == 0) {
-               ERROR("Metadata resource cannot begin with end-of-directory entry!");
-               ret = WIMLIB_ERR_INVALID_DENTRY;
+               WARNING("Metadata resource begins with end-of-directory entry "
+                       "(treating as empty image)");
+               FREE(root);
+               root = NULL;
+               goto out_success;
        }
 
        if (ret) {
@@ -140,6 +152,16 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
                goto out_free_security_data;
        }
 
+       if (dentry_has_long_name(root) || dentry_has_short_name(root)) {
+               WARNING("The root directory has a nonempty name (removing it)");
+               FREE(root->file_name);
+               FREE(root->short_name);
+               root->file_name = NULL;
+               root->short_name = NULL;
+               root->file_name_nbytes = 0;
+               root->short_name_nbytes = 0;
+       }
+
        /* This is the root dentry, so set its parent to itself. */
        root->parent = root;
 
@@ -156,19 +178,19 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
        if (ret)
                goto out_free_dentry_tree;
 
-       if (!wim->all_images_verified) {
-               DEBUG("Running miscellaneous verifications on the dentry tree");
-               for_lookup_table_entry(wim->lookup_table, lte_zero_real_refcnt, NULL);
-               ret = for_dentry_in_tree(root, verify_dentry, wim);
+
+       DEBUG("Running miscellaneous verifications on the dentry tree");
+       image_for_each_inode(inode, imd) {
+               ret = verify_inode(inode, security_data);
                if (ret)
                        goto out_free_dentry_tree;
        }
-
        DEBUG("Done reading image metadata");
-
+out_success:
        imd->root_dentry = root;
        imd->security_data = security_data;
        INIT_LIST_HEAD(&imd->unhashed_streams);
+       ret = 0;
        goto out_free_buf;
 out_free_dentry_tree:
        free_dentry_tree(root, wim->lookup_table);
@@ -214,7 +236,7 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size,
 
 /* Write the metadata resource for the current WIM image. */
 int
-write_metadata_resource(WIMStruct *w)
+write_metadata_resource(WIMStruct *wim)
 {
        u8 *buf;
        u8 *p;
@@ -226,13 +248,13 @@ write_metadata_resource(WIMStruct *w)
        struct wim_security_data *sd;
        struct wim_image_metadata *imd;
 
-       wimlib_assert(w->out_fd != -1);
-       wimlib_assert(w->current_image != WIMLIB_NO_IMAGE);
+       wimlib_assert(wim->out_fd != -1);
+       wimlib_assert(wim->current_image != WIMLIB_NO_IMAGE);
 
        DEBUG("Writing metadata resource for image %d (offset = %"PRIu64")",
-             w->current_image, filedes_offset(w->out_fd));
+             wim->current_image, filedes_offset(wim->out_fd));
 
-       imd = w->image_metadata[w->current_image - 1];
+       imd = wim->image_metadata[wim->current_image - 1];
 
        root = imd->root_dentry;
        sd = imd->security_data;
@@ -282,14 +304,14 @@ write_metadata_resource(WIMStruct *w)
 
        /* Get the lookup table entry for the metadata resource so we can update
         * it. */
-       lte = wim_get_current_image_metadata(w)->metadata_lte;
+       lte = wim_get_current_image_metadata(wim)->metadata_lte;
 
        /* Write the metadata resource to the output WIM using the proper
         * compression type.  The lookup table entry for the metadata resource
         * is updated. */
        ret = write_wim_resource_from_buffer(buf, metadata_original_size,
-                                            w->out_fd,
-                                            wimlib_get_compression_type(w),
+                                            wim->out_fd,
+                                            wim->compression_type,
                                             &lte->output_resource_entry,
                                             lte->hash);
        /* Note that although the SHA1 message digest of the metadata resource