archive-zip: write uncompressed size into header even with streaming

We record the uncompressed and compressed sizes and the CRC of streamed files as zero in the local header of the file. The actual values are recorded in an extra data descriptor after the file content, and in the usual ZIP directory entry at the end of the archive. While we know the compressed size and the CRC only after we processed the contents, we actually know the uncompressed size right from the start. And for files that we store uncompressed we also already know their final size. Do it like InfoZIP's zip and recored the known values, even though they can be reconstructed using the ZIP directory and the data descriptors alone. InfoZIP's unzip worked fine before, but NetBSD's version actually depends on these fields. The uncompressed size is already set by sha1_object_info(). We just need to initialize the compressed size to zero or the uncompressed size depending on the compression method (0 means storing). The CRC was propertly initialized already. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jan 6, 2013 at 16:20 UTC 5ea2c847c5938e9868f15a273869e54c6ed4c79c
1 file changed +2 -5
archive-zip.c
+2 -5
@@ -208,7 +208,7 @@ static int write_zip_entry(struct archiver_args *args,
208 (mode & 0111) ? ((mode) << 16) : 0;
209 if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
210 method = 8;
211 - compressed_size = size;
211 + compressed_size = (method == 0) ? size : 0;
212
213 if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
214 size > big_file_threshold) {
@@ -276,10 +276,7 @@ static int write_zip_entry(struct archiver_args *args,
276 copy_le16(header.compression_method, method);
277 copy_le16(header.mtime, zip_time);
278 copy_le16(header.mdate, zip_date);
279 - if (flags & ZIP_STREAM)
280 - set_zip_header_data_desc(&header, 0, 0, 0);
281 - else
282 - set_zip_header_data_desc(&header, size, compressed_size, crc);
279 + set_zip_header_data_desc(&header, size, compressed_size, crc);
280 copy_le16(header.filename_length, pathlen);
281 copy_le16(header.extra_length, 0);
282 write_or_die(1, &header, ZIP_LOCAL_HEADER_SIZE);