]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
A couple of changes to the experimental new extra block, as suggested by Steven Schweda.
authorTim Kientzle <kientzle@acm.org>
Tue, 31 Dec 2013 04:51:26 +0000 (20:51 -0800)
committerTim Kientzle <kientzle@acm.org>
Tue, 31 Dec 2013 04:51:26 +0000 (20:51 -0800)
 * Name changed from 'at' to 'LA' (Local Attributes)
 * Trimmed 'version made by' down to just 1 byte system code

libarchive/archive_read_support_format_zip.c
libarchive/archive_write_set_format_zip.c
libarchive/test/test_write_format_zip_compression_store.c
libarchive/test/test_write_format_zip_file.c
libarchive/test/test_write_format_zip_file_zip64.c

index b0d7858d318cbc301791c0cf88772d85bdae4e79..3ac6085e82fb6d25585c44cab3be132e6f693148 100644 (file)
@@ -339,13 +339,13 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
                        }
                        break;
                }
-               case 0x7461:
-                       /* Experimental 'at' field */
-                       if (datasize >= 2) {
-                               zip_entry->system
-                                   = archive_le16dec(p + offset) >> 8;
-                               offset += 2;
-                               datasize -= 2;
+               case 0x414C:
+                       /* Experimental 'LA' field */
+                       if (datasize >= 1) {
+                               // 1 byte system identifier
+                               zip_entry->system = p[offset];
+                               offset += 1;
+                               datasize -= 1;
                        }
                        if (datasize >= 2) {
                                // 2 byte "internal file attributes"
@@ -353,6 +353,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
                                datasize -= 2;
                        }
                        if (datasize >= 4) {
+                               // 4 byte "external file attributes"
                                uint32_t external_attributes
                                    = archive_le32dec(p + offset);
                                if (zip_entry->system == 3) {
index f28c59ea707e16546c3ce91fe35c1cb782f649ec..ad4e6b058d2c617afb33043bc7bae89dc4aedbaa 100644 (file)
@@ -576,6 +576,10 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
        memset(local_extra, 0, sizeof(local_extra));
        e = local_extra;
 
+       /* First, extra blocks that are the same between
+        * the local file header and the central directory.
+        * We format them once and then duplicate them. */
+
        /* UT timestamp, length depends on what timestamps are set. */
        memcpy(e, "UT", 2);
        archive_le16enc(e + 2,
@@ -613,12 +617,17 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
        e += 4;
 
        /* Copy UT and ux into central directory as well. */
-       /* (Zip64 extended data varies between local header and
-        * central directory, so we cannot just copy it.) */
        zip->file_header_extra_offset = zip->central_directory_bytes;
        cd_extra = cd_alloc(zip, e - local_extra);
        memcpy(cd_extra, local_extra, e - local_extra);
 
+       /*
+        * Following extra blocks vary between local header and
+        * central directory. These are the local header versions.
+        * Central directory versions get formatted in
+        * archive_write_zip_finish_entry() below.
+        */
+
        /* "[Zip64 entry] in the local header MUST include BOTH
         * original [uncompressed] and compressed size fields." */
        if (zip->entry_uses_zip64) {
@@ -632,13 +641,12 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
                archive_le16enc(zip64_start + 2, e - (zip64_start + 4));
        }
 
-       { /* Experimental 'at' extension to support streaming. */
+       { /* Experimental 'LA' extension to improve streaming. */
                unsigned char *external_info = e;
-               memcpy(e, "at\000\000", 4);
+               memcpy(e, "LA\000\000", 4); // 0x414C + 2-byte length
                e += 4;
-               archive_le16enc(e, /* system + version written by */
-                   3 * 256 + version_needed);
-               e += 2;
+               e[0] = 3; /* system */
+               e += 1;
                archive_le16enc(e, 0); /* internal file attributes */
                e += 2;
                archive_le32enc(e,  /* external file attributes */
index 2aa4146e9e2cf1260f35cf1123a106db4d42e02f..1c48620645063a1b39968943c8bfb1c32054ddc1 100644 (file)
@@ -209,7 +209,7 @@ DEFINE_TEST(test_write_format_zip_compression_store)
        assertEqualInt(i4(q + 18), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */
        assertEqualInt(i4(q + 22), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */
        assertEqualInt(i2(q + 26), strlen(file_name)); /* Pathname length */
-       assertEqualInt(i2(q + 28), 40); /* Extra field length */
+       assertEqualInt(i2(q + 28), 39); /* Extra field length */
        assertEqualMem(q + 30, file_name, strlen(file_name)); /* Pathname */
        extra_start = q = q + 30 + strlen(file_name);
        assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
@@ -228,11 +228,11 @@ DEFINE_TEST(test_write_format_zip_compression_store)
        assertEqualInt(i4(q + 11), file_gid); /* 'Ux' GID */
        q = q + 4 + i2(q + 2);
 
-       assertEqualInt(i2(q), 0x7461); /* 'at' experimental extension header */
-       assertEqualInt(i2(q + 2), 8); /* 'at' size */
-       assertEqualInt(i2(q + 4), 3 * 256 + 10); /* version made by */
-       assertEqualInt(i2(q + 6), 0); /* internal file attributes */
-       assertEqualInt(i4(q + 8) >> 16 & 01777, file_perm); /* external file attributes */
+       assertEqualInt(i2(q), 0x414c); /* 'LA' experimental extension header */
+       assertEqualInt(i2(q + 2), 7); /* size */
+       assertEqualInt(q[4], 3); /* system */
+       assertEqualInt(i2(q + 5), 0); /* internal file attributes */
+       assertEqualInt(i4(q + 7) >> 16 & 01777, file_perm); /* external file attributes */
        q = q + 4 + i2(q + 2);
 
        assert(q == extra_start + i2(local_header + 28));
@@ -298,7 +298,7 @@ DEFINE_TEST(test_write_format_zip_compression_store)
        assertEqualInt(i4(q + 18), 0); /* Compressed size */
        assertEqualInt(i4(q + 22), 0); /* Uncompressed size */
        assertEqualInt(i2(q + 26), strlen(folder_name)); /* Pathname length */
-       assertEqualInt(i2(q + 28), 40); /* Extra field length */
+       assertEqualInt(i2(q + 28), 39); /* Extra field length */
        assertEqualMem(q + 30, folder_name, strlen(folder_name)); /* Pathname */
        extra_start = q = q + 30 + strlen(folder_name);
        assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
@@ -316,11 +316,11 @@ DEFINE_TEST(test_write_format_zip_compression_store)
        assertEqualInt(i4(q + 11), folder_gid); /* 'ux' GID */
        q = q + 4 + i2(q + 2);
 
-       assertEqualInt(i2(q), 0x7461); /* 'at' experimental extension header */
-       assertEqualInt(i2(q + 2), 8); /* 'at' size */
-       assertEqualInt(i2(q + 4), 3 * 256 + 20); /* version made by */
-       assertEqualInt(i2(q + 6), 0); /* internal file attributes */
-       assertEqualInt(i4(q + 8) >> 16 & 01777, folder_perm); /* external file attributes */
+       assertEqualInt(i2(q), 0x414c); /* 'LA' experimental extension header */
+       assertEqualInt(i2(q + 2), 7); /* size */
+       assertEqualInt(q[4], 3); /* system */
+       assertEqualInt(i2(q + 5), 0); /* internal file attributes */
+       assertEqualInt(i4(q + 7) >> 16 & 01777, folder_perm); /* external file attributes */
        q = q + 4 + i2(q + 2);
 
        assert(q == extra_start + i2(local_header + 28));
index 7825ef55b7ea40d4bfee9627bb620849146ab825..0216fef3454e20d566b8afc8f491c76ce394fdd6 100644 (file)
@@ -196,7 +196,7 @@ DEFINE_TEST(test_write_format_zip_file)
        /* assertEqualInt(i4(p + 18), sizeof(file_data)); */ /* Compressed size */
        /* assertEqualInt(i4(p + 22), sizeof(file_data)); */ /* Uncompressed size not stored because we're using length-at-end. */
        assertEqualInt(i2(p + 26), strlen(file_name)); /* Pathname length */
-       assertEqualInt(i2(p + 28), 36); /* Extra field length */
+       assertEqualInt(i2(p + 28), 35); /* Extra field length */
        assertEqualMem(p + 30, file_name, strlen(file_name)); /* Pathname */
        p = extension_start = local_header + 30 + strlen(file_name);
        extension_end = extension_start + i2(local_header + 28);
@@ -216,11 +216,11 @@ DEFINE_TEST(test_write_format_zip_file)
        assertEqualInt(i4(p + 11), file_gid); /* 'Ux' GID */
        p += 4 + i2(p + 2);
 
-       assertEqualInt(i2(p), 0x7461); /* 'at' experimental extension header */
-       assertEqualInt(i2(p + 2), 8); /* 'at' size */
-       assertEqualInt(i2(p + 4), 3 * 256 + 20); /* version made by */
-       assertEqualInt(i2(p + 6), 0); /* internal file attributes */
-       assertEqualInt(i4(p + 8) >> 16 & 01777, file_perm); /* external file attributes */
+       assertEqualInt(i2(p), 0x414c); /* 'LA' experimental extension header */
+       assertEqualInt(i2(p + 2), 7); /* 'at' size */
+       assertEqualInt(p[4], 3); /* system */
+       assertEqualInt(i2(p + 5), 0); /* internal file attributes */
+       assertEqualInt(i4(p + 7) >> 16 & 01777, file_perm); /* external file attributes */
        p += 4 + i2(p + 2);
 
        /* Just in case: Report any extra extensions. */
index 1f47040b1ed4794a78dca8d6fa0c21d638b772e9..3dc512ade02c6f647559611f6ffd0cc9ccded4e4 100644 (file)
@@ -223,7 +223,7 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
        /* assertEqualInt(i4(p + 18), sizeof(file_data)); */ /* Compressed size */
        /* assertEqualInt(i4(p + 22), sizeof(file_data)); */ /* Uncompressed size not stored because we're using length-at-end. */
        assertEqualInt(i2(p + 26), strlen(file_name)); /* Pathname length */
-       assertEqualInt(i2(p + 28), 56); /* Extra field length */
+       assertEqualInt(i2(p + 28), 55); /* Extra field length */
        assertEqualMem(p + 30, file_name, strlen(file_name)); /* Pathname */
        p = extension_start = local_header + 30 + strlen(file_name);
        extension_end = extension_start + i2(local_header + 28);
@@ -249,11 +249,11 @@ DEFINE_TEST(test_write_format_zip_file_zip64)
        /* compressed file size we can't verify here */
        p += 4 + i2(p + 2);
 
-       assertEqualInt(i2(p), 0x7461); /* 'at' experimental extension header */
-       assertEqualInt(i2(p + 2), 8); /* 'at' size */
-       assertEqualInt(i2(p + 4), 3 * 256 + 45); /* version made by */
-       assertEqualInt(i2(p + 6), 0); /* internal file attributes */
-       assertEqualInt(i4(p + 8) >> 16 & 01777, file_perm); /* external file attributes */
+       assertEqualInt(i2(p), 0x414c); /* 'LA' experimental extension header */
+       assertEqualInt(i2(p + 2), 7); /* 'at' size */
+       assertEqualInt(p[4], 3); /* system */
+       assertEqualInt(i2(p + 5), 0); /* internal file attributes */
+       assertEqualInt(i4(p + 7) >> 16 & 01777, file_perm); /* external file attributes */
        p += 4 + i2(p + 2);
 
        /* Just in case: Report any extra extensions. */