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));
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. */
/* Verify GNU tar magic/version fields */
assertEqualMem(buff + 257, "ustar \0", 8);
- assertEqualInt(14336, used);
+ assertEqualInt(15360, used);
/*
*
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.
*/