From: Eric Biggers Date: Tue, 7 Jan 2014 20:33:56 +0000 (-0600) Subject: Handle streams with uncompressed size 4 GiB consistently X-Git-Tag: v1.6.1~83 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=f36b35733a7e0bdb6b3e1920d7e6893bd0dc4d55 Handle streams with uncompressed size 4 GiB consistently The read code went to 8-byte chunk entries for uncompressed size > 4294967296, whereas the write code went to 8-byte chunk entries for uncompressed size >= 4294967296. Change both to >= 4294967296. Confirmed that WIMGAPI (Windows 7) seems to have this behavior. --- diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index 3b863f46..488ea6a9 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -170,6 +170,15 @@ struct alt_chunk_table_header_disk { * the chunks (4 bytes per entry). */ } _packed_attribute; +static inline unsigned int +get_chunk_entry_size(u64 res_size, bool is_alt) +{ + if (res_size <= UINT32_MAX || is_alt) + return 4; + else + return 8; +} + /* Functions to read streams */ extern int diff --git a/src/resource.c b/src/resource.c index b7713977..6e47dff7 100644 --- a/src/resource.c +++ b/src/resource.c @@ -253,11 +253,9 @@ read_compressed_wim_resource(const struct wim_resource_spec * const rspec, const u64 num_chunk_entries = (alt_chunk_table ? num_chunks : num_chunks - 1); /* Set the size of each chunk table entry based on the resource's - * uncompressed size. XXX: Does the alternate chunk table really - * always have 4-byte entries? */ - const u64 chunk_entry_size = - (rspec->uncompressed_size > (1ULL << 32) && !alt_chunk_table) - ? 8 : 4; + * uncompressed size. */ + const u64 chunk_entry_size = get_chunk_entry_size(rspec->uncompressed_size, + alt_chunk_table); /* Calculate the size of the chunk table in bytes. */ const u64 chunk_table_size = num_chunk_entries * chunk_entry_size; diff --git a/src/write.c b/src/write.c index 7e597e18..411fed9a 100644 --- a/src/write.c +++ b/src/write.c @@ -409,16 +409,6 @@ struct write_streams_ctx { u64 chunks_start_offset; }; -static u64 -get_chunk_entry_size(u64 res_size, int write_resource_flags) -{ - if (res_size <= UINT32_MAX || - (write_resource_flags & WIM_RESHDR_FLAG_PACKED_STREAMS)) - return 4; - else - return 8; -} - /* Reserve space for the chunk table and prepare to accumulate the chunk table * in memory. */ static int @@ -470,7 +460,8 @@ begin_chunk_table(struct write_streams_ctx *ctx, u64 res_expected_size) * are unknown. */ reserve_size = expected_num_chunk_entries * get_chunk_entry_size(res_expected_size, - ctx->write_resource_flags); + 0 != (ctx->write_resource_flags & + WIM_RESHDR_FLAG_PACKED_STREAMS)); if (ctx->write_resource_flags & WRITE_RESOURCE_FLAG_PACK_STREAMS) reserve_size += sizeof(struct alt_chunk_table_header_disk); memset(ctx->chunk_csizes, 0, reserve_size); @@ -517,7 +508,8 @@ end_chunk_table(struct write_streams_ctx *ctx, u64 res_actual_size, actual_num_chunk_entries--; chunk_entry_size = get_chunk_entry_size(res_actual_size, - ctx->write_resource_flags); + 0 != (ctx->write_resource_flags & + WIM_RESHDR_FLAG_PACKED_STREAMS)); typedef le64 __attribute__((may_alias)) aliased_le64_t; typedef le32 __attribute__((may_alias)) aliased_le32_t;