]> wimlib.net Git - wimlib/blobdiff - src/extract.c
Disallow empty blobs from being read
[wimlib] / src / extract.c
index 56ec644a0b2d31aad4fcb68fe32b442151daf557..83477f1337eb897cea1b5a41d90d8ddee8e0ac69 100644 (file)
 #include "wimlib/resource.h"
 #include "wimlib/security.h"
 #include "wimlib/unix_data.h"
-#ifdef __WIN32__
-#  include "wimlib/win32.h" /* for realpath() equivalent */
-#endif
-#include "wimlib/xml.h"
 #include "wimlib/wildcard.h"
 #include "wimlib/wim.h"
+#include "wimlib/win32.h" /* for realpath() equivalent */
+#include "wimlib/xml.h"
 
 #define WIMLIB_EXTRACT_FLAG_FROM_PIPE   0x80000000
 #define WIMLIB_EXTRACT_FLAG_IMAGEMODE   0x40000000
@@ -98,7 +96,7 @@ do_file_extract_progress(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
 }
 
 static int
-start_file_phase(struct apply_ctx *ctx, uint64_t end_file_count, enum wimlib_progress_msg msg)
+start_file_phase(struct apply_ctx *ctx, u64 end_file_count, enum wimlib_progress_msg msg)
 {
        ctx->progress.extract.current_file_count = 0;
        ctx->progress.extract.end_file_count = end_file_count;
@@ -106,13 +104,13 @@ start_file_phase(struct apply_ctx *ctx, uint64_t end_file_count, enum wimlib_pro
 }
 
 int
-start_file_structure_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+start_file_structure_phase(struct apply_ctx *ctx, u64 end_file_count)
 {
        return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
 }
 
 int
-start_file_metadata_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+start_file_metadata_phase(struct apply_ctx *ctx, u64 end_file_count)
 {
        return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
 }
@@ -181,10 +179,12 @@ read_pwm_blob_header(WIMStruct *pwm, struct blob_descriptor *blob,
        reshdr.offset_in_wim = pwm->in_fd.offset;
        reshdr.uncompressed_size = le64_to_cpu(buf.blob_hdr.uncompressed_size);
        wim_res_hdr_to_desc(&reshdr, pwm, rdesc);
-       blob_set_is_located_in_wim_resource(blob, rdesc);
-       blob->size = rdesc->uncompressed_size;
-       blob->offset_in_res = 0;
+       blob_set_is_located_in_nonsolid_wim_resource(blob, rdesc);
        blob->is_metadata = (rdesc->flags & WIM_RESHDR_FLAG_METADATA) != 0;
+
+       if (unlikely(blob->size == 0))
+               return WIMLIB_ERR_INVALID_PIPABLE_WIM;
+
        return 0;
 
 read_error:
@@ -234,11 +234,8 @@ read_blobs_from_pipe(struct apply_ctx *ctx,
                    && (needed_blob = lookup_blob(blob_table, found_blob->hash))
                    && (needed_blob->out_refcnt))
                {
-                       needed_blob->offset_in_res = found_blob->offset_in_res;
-                       needed_blob->size = found_blob->size;
-
                        blob_unset_is_located_in_wim_resource(found_blob);
-                       blob_set_is_located_in_wim_resource(needed_blob, rdesc);
+                       blob_set_is_located_in_nonsolid_wim_resource(needed_blob, rdesc);
 
                        ret = (*cbs->begin_blob)(needed_blob,
                                                 cbs->begin_blob_ctx);
@@ -511,8 +508,8 @@ end_extract_blob_wrapper(struct blob_descriptor *blob, int status, void *_ctx)
  * MAX_OPEN_FILES locations, as measured by the 'out_refcnt' of each blob.
  * Therefore, the apply_operations implementation need not worry about running
  * out of file descriptors, unless it might open more than one file descriptor
- * per nominal destination (e.g. Win32 currently might because the destination
- * file system might not support hard links).
+ * per 'blob_extraction_target' (e.g. Win32 currently might because the
+ * destination file system might not support hard links).
  */
 int
 extract_blob_list(struct apply_ctx *ctx,