]> wimlib.net Git - wimlib/blobdiff - src/write.c
libFuzzer: add encoding fuzzer
[wimlib] / src / write.c
index 4edf64e3350bebfc0a80f28612290a6bcef43fdd..4bf1b2bedf5e181fa9f975fec74f66ba7fdc47b9 100644 (file)
@@ -19,7 +19,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
@@ -301,7 +301,8 @@ struct write_blobs_progress_data {
 
 static int
 do_write_blobs_progress(struct write_blobs_progress_data *progress_data,
-                       u64 complete_size, u32 complete_count, bool discarded)
+                       u64 complete_size, u64 complete_compressed_size,
+                       u32 complete_count, bool discarded)
 {
        union wimlib_progress_info *progress = &progress_data->progress;
        int ret;
@@ -316,6 +317,8 @@ do_write_blobs_progress(struct write_blobs_progress_data *progress_data,
                }
        } else {
                progress->write_streams.completed_bytes += complete_size;
+               progress->write_streams.completed_compressed_bytes +=
+                       complete_compressed_size;
                progress->write_streams.completed_streams += complete_count;
        }
 
@@ -503,8 +506,8 @@ end_chunk_table(struct write_blobs_ctx *ctx, u64 res_actual_size,
                                                0 != (ctx->write_resource_flags &
                                                      WRITE_RESOURCE_FLAG_SOLID));
 
-       typedef le64 _may_alias_attribute aliased_le64_t;
-       typedef le32 _may_alias_attribute aliased_le32_t;
+       typedef le64 __attribute__((may_alias)) aliased_le64_t;
+       typedef le32 __attribute__((may_alias)) aliased_le32_t;
 
        if (chunk_entry_size == 4) {
                aliased_le32_t *entries = (aliased_le32_t*)ctx->chunk_csizes;
@@ -713,7 +716,9 @@ write_blob_begin_read(struct blob_descriptor *blob, void *_ctx)
                                 * output reference count to the duplicate blob
                                 * in the former case.  */
                                ret = do_write_blobs_progress(&ctx->progress_data,
-                                                             blob->size, 1, true);
+                                                             blob->size,
+                                                             blob->size,
+                                                             1, true);
                                list_del(&blob->write_blobs_list);
                                list_del(&blob->blob_table_list);
                                if (new_blob->will_be_in_output_wim)
@@ -762,7 +767,7 @@ write_blob_uncompressed(struct blob_descriptor *blob, struct filedes *out_fd)
        if (filedes_seek(out_fd, begin_offset) == -1)
                return 0;
 
-       ret = extract_blob_to_fd(blob, out_fd);
+       ret = extract_blob_to_fd(blob, out_fd, false);
        if (ret) {
                /* Error reading the uncompressed data.  */
                if (out_fd->offset == begin_offset &&
@@ -867,8 +872,7 @@ write_chunk(struct write_blobs_ctx *ctx, const void *cchunk,
 {
        int ret;
        struct blob_descriptor *blob;
-       u32 completed_blob_count;
-       u32 completed_size;
+       u32 completed_blob_count = 0;
 
        blob = list_entry(ctx->blobs_being_compressed.next,
                          struct blob_descriptor, write_blobs_list);
@@ -915,8 +919,6 @@ write_chunk(struct write_blobs_ctx *ctx, const void *cchunk,
 
        ctx->cur_write_blob_offset += usize;
 
-       completed_size = usize;
-       completed_blob_count = 0;
        if (ctx->write_resource_flags & WRITE_RESOURCE_FLAG_SOLID) {
                /* Wrote chunk in solid mode.  It may have finished multiple
                 * blobs.  */
@@ -973,7 +975,7 @@ write_chunk(struct write_blobs_ctx *ctx, const void *cchunk,
                }
        }
 
-       return do_write_blobs_progress(&ctx->progress_data, completed_size,
+       return do_write_blobs_progress(&ctx->progress_data, usize, csize,
                                       completed_blob_count, false);
 
 write_error:
@@ -1287,15 +1289,18 @@ write_raw_copy_resources(struct list_head *raw_copy_blobs,
                blob->rdesc->raw_copy_ok = 1;
 
        list_for_each_entry(blob, raw_copy_blobs, write_blobs_list) {
+               u64 compressed_size = 0;
+
                if (blob->rdesc->raw_copy_ok) {
                        /* Write each solid resource only one time.  */
                        ret = write_raw_copy_resource(blob->rdesc, out_fd);
                        if (ret)
                                return ret;
                        blob->rdesc->raw_copy_ok = 0;
+                       compressed_size = blob->rdesc->size_in_wim;
                }
                ret = do_write_blobs_progress(progress_data, blob->size,
-                                             1, false);
+                                             compressed_size, 1, false);
                if (ret)
                        return ret;
        }
@@ -1546,7 +1551,6 @@ write_blob_list(struct list_head *blob_list,
         * specified number of threads, unless the upper bound on the number
         * bytes needing to be compressed is less than a heuristic value.  */
        if (num_nonraw_bytes != 0 && out_ctype != WIMLIB_COMPRESSION_TYPE_NONE) {
-       #ifdef ENABLE_MULTITHREADED_COMPRESSION
                if (num_nonraw_bytes > max(2000000, out_chunk_size)) {
                        ret = new_parallel_chunk_compressor(out_ctype,
                                                            out_chunk_size,
@@ -1558,7 +1562,6 @@ write_blob_list(struct list_head *blob_list,
                                        wimlib_get_error_string(ret));
                        }
                }
-       #endif
 
                if (ctx.compressor == NULL) {
                        ret = new_serial_chunk_compressor(out_ctype, out_chunk_size,
@@ -1734,7 +1737,7 @@ write_wim_resource_from_buffer(const void *buf,
        }
 
        blob_set_is_located_in_attached_buffer(&blob, (void *)buf, buf_size);
-       sha1_buffer(buf, buf_size, blob.hash);
+       sha1(buf, buf_size, blob.hash);
        blob.unhashed = 0;
        blob.is_metadata = is_metadata;
 
@@ -2590,14 +2593,15 @@ write_pipable_wim(WIMStruct *wim, int image, int write_flags,
        /* At this point, the header at the beginning of the file has already
         * been written.  */
 
-       /* For efficiency, when wimlib adds an image to the WIM with
-        * wimlib_add_image(), the SHA-1 message digests of files are not
-        * calculated; instead, they are calculated while the files are being
-        * written.  However, this does not work when writing a pipable WIM,
-        * since when writing a blob to a pipable WIM, its SHA-1 message digest
-        * needs to be known before the blob data is written.  Therefore, before
-        * getting much farther, we need to pre-calculate the SHA-1 message
-        * digests of all blobs that will be written.  */
+       /*
+        * For efficiency, wimlib normally delays calculating each newly added
+        * stream's hash until while that stream being written, or just before
+        * it is written.  However, when writing a pipable WIM (potentially to a
+        * pipe), we first have to write the metadata resources, which contain
+        * all the hashes.  Moreover each blob is prefixed with its hash (struct
+        * pwm_blob_hdr).  Thus, we have to calculate all the hashes before
+        * writing anything.
+        */
        ret = wim_checksum_unhashed_blobs(wim);
        if (ret)
                return ret;
@@ -3270,7 +3274,7 @@ overwrite_wim_via_tmpfile(WIMStruct *wim, int write_flags, unsigned num_threads)
        if (ret) {
                ERROR_WITH_ERRNO("Failed to rename `%"TS"' to `%"TS"'",
                                 tmpfile, wim->filename);
-       #ifdef __WIN32__
+       #ifdef _WIN32
                if (ret < 0)
        #endif
                {