]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Issue #901: Sparse files with long name get renamed.
authorJoerg Sonnenberger <joerg@bec.de>
Fri, 21 Apr 2017 00:22:55 +0000 (02:22 +0200)
committerJoerg Sonnenberger <joerg@bec.de>
Fri, 21 Apr 2017 00:22:55 +0000 (02:22 +0200)
The original ustar header has a 100 character limit for the file name.
With the POSIX interchange format, an additional header attribute
contains the full path and libarchive tries to cut it to something
sensible. The GNU sparse file extension on the other hand also likes to
mangle the ustar header field to include a marker and contains yet
another attribute for the original path. If the name was truncated
earlier, this attribute would get the incorrect truncated name.

libarchive/archive_write_set_format_pax.c
libarchive/test/test_write_format_pax.c

index 5fdfd9dd80aa09385b6a6e2ab2fc2062c399fcff..0eaf733cd9aaf08e161ed3092be154c4b88c1a8e 100644 (file)
@@ -1196,8 +1196,12 @@ archive_write_pax_header(struct archive_write *a,
                            "GNU.sparse.major", 1);
                        add_pax_attr_int(&(pax->pax_header),
                            "GNU.sparse.minor", 0);
+                       /*
+                        * Make sure to store the original path, since
+                        * truncation to ustar limit happened already.
+                        */
                        add_pax_attr(&(pax->pax_header),
-                           "GNU.sparse.name", entry_name.s);
+                           "GNU.sparse.name", path);
                        add_pax_attr_int(&(pax->pax_header),
                            "GNU.sparse.realsize",
                            archive_entry_size(entry_main));
index 1bae0050f0811227af823e13b89261538ba79534..41a423a96a0e75308a363587a9cca173fec2c4ff 100644 (file)
@@ -80,13 +80,19 @@ DEFINE_TEST(test_write_format_pax)
        /*
         * "file3" is sparse file and has hole size of which is
         * 1024000 bytes, and has 8 bytes data after the hole.
+        *
+        * Pad the filename to make it larger than the ustar limit.
+        * It should still read back correctly.
         */
        assert((ae = archive_entry_new()) != NULL);
        archive_entry_set_atime(ae, 2, 20);
        archive_entry_set_birthtime(ae, 3, 30);
        archive_entry_set_ctime(ae, 4, 40);
        archive_entry_set_mtime(ae, 5, 50);
-       archive_entry_copy_pathname(ae, "file3");
+       archive_entry_copy_pathname(ae, "file3"
+           "_123456789_123456789_123456789_123456789_123456789"
+           "_123456789_123456789_123456789_123456789_123456789"
+           "_123456789_123456789_123456789_123456789_123456789");
        archive_entry_set_mode(ae, S_IFREG | 0755);
        archive_entry_set_size(ae, 1024008);
        archive_entry_sparse_add_entry(ae, 1024000, 8);
@@ -171,7 +177,11 @@ DEFINE_TEST(test_write_format_pax)
        assertEqualInt(40, archive_entry_ctime_nsec(ae));
        assertEqualInt(5, archive_entry_mtime(ae));
        assertEqualInt(50, archive_entry_mtime_nsec(ae));
-       assertEqualString("file3", archive_entry_pathname(ae));
+       assertEqualString("file3"
+           "_123456789_123456789_123456789_123456789_123456789"
+           "_123456789_123456789_123456789_123456789_123456789"
+           "_123456789_123456789_123456789_123456789_123456789",
+           archive_entry_pathname(ae));
        assert((S_IFREG | 0755) == archive_entry_mode(ae));
        assertEqualInt(1024008, archive_entry_size(ae));
        assertEqualInt(1, archive_entry_sparse_reset(ae));