]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fall back to base-256 encoding for UID/GID like GNU tar does. 112/head
authorNils Gladitz <nilsgladitz@gmail.com>
Wed, 8 Apr 2015 18:58:29 +0000 (20:58 +0200)
committerNils Gladitz <nilsgladitz@gmail.com>
Wed, 8 Apr 2015 18:58:29 +0000 (20:58 +0200)
libarchive/archive_write_set_format_gnutar.c
libarchive/test/test_write_format_gnutar.c

index 13942c132b185cd727efe60e4704a0ee79177673..647079de6320f2e303ad17b57e9e03e9e2df4962 100644 (file)
@@ -644,18 +644,18 @@ archive_format_gnutar_header(struct archive_write *a, char h[512],
        format_octal(archive_entry_mode(entry) & 07777,
            h + GNUTAR_mode_offset, GNUTAR_mode_size);
 
-       /* TODO: How does GNU tar handle large UIDs? */
-       if (format_octal(archive_entry_uid(entry),
-           h + GNUTAR_uid_offset, GNUTAR_uid_size)) {
+       /* GNU tar supports base-256 here, so should never overflow. */
+       if (format_number(archive_entry_uid(entry), h + GNUTAR_uid_offset,
+               GNUTAR_uid_size, GNUTAR_uid_max_size)) {
                archive_set_error(&a->archive, ERANGE,
                    "Numeric user ID %jd too large",
                    (intmax_t)archive_entry_uid(entry));
                ret = ARCHIVE_FAILED;
        }
 
-       /* TODO: How does GNU tar handle large GIDs? */
-       if (format_octal(archive_entry_gid(entry),
-           h + GNUTAR_gid_offset, GNUTAR_gid_size)) {
+       /* GNU tar supports base-256 here, so should never overflow. */
+       if (format_number(archive_entry_gid(entry), h + GNUTAR_gid_offset,
+               GNUTAR_gid_size, GNUTAR_gid_max_size)) {
                archive_set_error(&a->archive, ERANGE,
                    "Numeric group ID %jd too large",
                    (intmax_t)archive_entry_gid(entry));
index 63ee6225f898c1ebdc28a1733a25db587bf27c2e..2a4c383e7afffddff93b2d19b2e3101d26502bd2 100644 (file)
@@ -159,6 +159,19 @@ DEFINE_TEST(test_write_format_gnutar)
        assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
        archive_entry_free(ae);
 
+       /*
+        * A file with large UID/GID that overflow octal encoding.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_copy_pathname(ae, "large_uid_gid");
+       archive_entry_set_mode(ae, S_IFREG | 0755);
+       archive_entry_set_size(ae, 8);
+       archive_entry_set_uid(ae, 123456789);
+       archive_entry_set_gid(ae, 987654321);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       archive_entry_free(ae);
+       assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9));
+
        /* TODO: support GNU tar sparse format and test it here. */
        /* See test_write_format_pax for an example of testing sparse files. */
 
@@ -173,7 +186,7 @@ DEFINE_TEST(test_write_format_gnutar)
        /* Verify GNU tar magic/version fields */
        assertEqualMem(buff + 257, "ustar  \0", 8);
 
-       assertEqualInt(14336, used);
+       assertEqualInt(15360, used);
 
        /*
         *
@@ -225,6 +238,15 @@ DEFINE_TEST(test_write_format_gnutar)
        assertEqualString(longfilename, archive_entry_symlink(ae));
        assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
 
+       /*
+        * Read file with large UID/GID.
+        */
+       assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+       assertEqualInt(123456789, archive_entry_uid(ae));
+       assertEqualInt(987654321, archive_entry_gid(ae));
+       assertEqualString("large_uid_gid", archive_entry_pathname(ae));
+       assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
+
        /*
         * Verify the end of the archive.
         */