Handle streams with uncompressed size 4 GiB consistently
authorEric Biggers <ebiggers3@gmail.com>
Tue, 7 Jan 2014 20:33:56 +0000 (14:33 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 7 Jan 2014 20:40:03 +0000 (14:40 -0600)
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.

include/wimlib/resource.h
src/resource.c
src/write.c

index 3b863f4654d66d1146c6070e42cd79810ddc1c1b..488ea6a99f2c2a8ddeec357ef69d8e7091ecf541 100644 (file)
@@ -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
index b7713977abbf7c5c03f46733b3b285e5f6ce4c06..6e47dff71da9c932f73d1cc89c14412d314f530c 100644 (file)
@@ -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;
index 7e597e18bf2410526a3225bb47946834fecd1f35..411fed9a349baa6f9c1411c9cae0cb8833bc4a14 100644 (file)
@@ -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;