From cacc2912aae997cf5bc5b51dace7bf30f2869644 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Tue, 31 Dec 2013 09:19:52 -0800 Subject: [PATCH] Only write the new 'LA' experimental extra block if it's explicitly enabled. Enable it in the appropriate tests. E.g., $ bsdtar cf - --format=zip --option zip:experimental . The syntax supports multiple experiments; use --option zip:experiment_la to enable just the 'LA' experiment. --- libarchive/archive_write_set_format_zip.c | 47 +++++++++++++++++-- libarchive/test/test_write_format_zip.c | 7 ++- .../test_write_format_zip_compression_store.c | 5 +- libarchive/test/test_write_format_zip_file.c | 2 + .../test/test_write_format_zip_file_zip64.c | 5 +- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c index ad4e6b058..70e68aa1b 100644 --- a/libarchive/archive_write_set_format_zip.c +++ b/libarchive/archive_write_set_format_zip.c @@ -82,6 +82,10 @@ struct cd_segment { unsigned char *p; }; +/* Bits used to enable/disable certain experimental features. */ +#define EXPERIMENT_LA 1 +#define EXPERIMENTS_ALL 0xffff + struct zip { int64_t entry_offset; @@ -95,6 +99,7 @@ struct zip { enum compression entry_compression; int entry_flags; int entry_uses_zip64; + int experiments; unsigned char *file_header; size_t file_header_extra_offset; @@ -197,6 +202,10 @@ archive_write_zip_options(struct archive_write *a, const char *key, int ret = ARCHIVE_FAILED; if (strcmp(key, "compression") == 0) { + /* + * Set compression to use on all future entries. + * This only affects regular files. + */ if (val == NULL || val[0] == 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "%s: compression option needs a compression name", @@ -214,15 +223,40 @@ archive_write_zip_options(struct archive_write *a, const char *key, ret = ARCHIVE_OK; } return (ret); + } else if (strcmp(key, "experimental") == 0) { + /* + * Enable/disable experimental features. + */ + if (val != NULL && *val != '\0') { + zip->experiments = EXPERIMENTS_ALL; + } else { + zip->experiments = 0; + } + return (ARCHIVE_OK); + } else if (strcmp(key, "experiment_la") == 0) { + /* + * Enable/disable experimental 'LA' extra block. + */ + if (val != NULL && *val != '\0') { + zip->experiments |= EXPERIMENT_LA; + } else { + zip->experiments &= ~EXPERIMENT_LA; + } + return (ARCHIVE_OK); } else if (strcmp(key, "fakecrc32") == 0) { - /* FOR TESTING ONLY: turn off CRC calculator to speed up - * certain complex tests. */ + /* + * FOR TESTING ONLY: disable CRC calculation to speed up + * certain complex tests. + */ if (val == NULL || val[0] == 0) { zip->crc32func = real_crc32; } else { zip->crc32func = fake_crc32; } } else if (strcmp(key, "hdrcharset") == 0) { + /* + * Set the character set used in translating filenames. + */ if (val == NULL || val[0] == 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "%s: hdrcharset option needs a character-set name", @@ -237,6 +271,12 @@ archive_write_zip_options(struct archive_write *a, const char *key, } return (ret); } else if (strcmp(key, "zip64") == 0) { + /* + * Bias decisions about Zip64: force them to be + * generated in certain cases where they are not + * forbidden or avoid them in certain cases where they + * are not strictly required. + */ zip->force_zip64 = (val != NULL && *val != '\0'); zip->avoid_zip64 = !zip->force_zip64; return (ARCHIVE_OK); @@ -641,7 +681,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry) archive_le16enc(zip64_start + 2, e - (zip64_start + 4)); } - { /* Experimental 'LA' extension to improve streaming. */ + if (zip->experiments & EXPERIMENT_LA) { + /* Experimental 'LA' extension to improve streaming. */ unsigned char *external_info = e; memcpy(e, "LA\000\000", 4); // 0x414C + 2-byte length e += 4; diff --git a/libarchive/test/test_write_format_zip.c b/libarchive/test/test_write_format_zip.c index 3a2a129fb..fc91f8550 100644 --- a/libarchive/test/test_write_format_zip.c +++ b/libarchive/test/test_write_format_zip.c @@ -530,6 +530,8 @@ DEFINE_TEST(test_write_format_zip) assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); write_contents(a); @@ -579,7 +581,10 @@ DEFINE_TEST(test_write_format_zip64) assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:zip64")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); write_contents(a); diff --git a/libarchive/test/test_write_format_zip_compression_store.c b/libarchive/test/test_write_format_zip_compression_store.c index 1c4862064..530464a48 100644 --- a/libarchive/test/test_write_format_zip_compression_store.c +++ b/libarchive/test/test_write_format_zip_compression_store.c @@ -98,7 +98,10 @@ DEFINE_TEST(test_write_format_zip_compression_store) /* Create new ZIP archive in memory without padding. */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:compression=store")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:compression=store")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); diff --git a/libarchive/test/test_write_format_zip_file.c b/libarchive/test/test_write_format_zip_file.c index 0216fef34..7bdc2d3cd 100644 --- a/libarchive/test/test_write_format_zip_file.c +++ b/libarchive/test/test_write_format_zip_file.c @@ -96,6 +96,8 @@ DEFINE_TEST(test_write_format_zip_file) /* Create a new archive in memory. */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); diff --git a/libarchive/test/test_write_format_zip_file_zip64.c b/libarchive/test/test_write_format_zip_file_zip64.c index 3dc512ade..40c055009 100644 --- a/libarchive/test/test_write_format_zip_file_zip64.c +++ b/libarchive/test/test_write_format_zip_file_zip64.c @@ -97,7 +97,10 @@ DEFINE_TEST(test_write_format_zip_file_zip64) /* Create a new archive in memory. */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:zip64")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_options(a, "zip:experimental")); assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); -- 2.47.2