diff --git a/lib/libarchive/archive_write_set_format_cpio_newc.c b/lib/libarchive/archive_write_set_format_cpio_newc.c index 37dd35af6313..6580b52faa34 100644 --- a/lib/libarchive/archive_write_set_format_cpio_newc.c +++ b/lib/libarchive/archive_write_set_format_cpio_newc.c @@ -176,9 +176,15 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry) cpio->entry_bytes_remaining = archive_entry_size(entry); cpio->padding = 3 & (-cpio->entry_bytes_remaining); + /* Write the symlink now. */ - if (p != NULL && *p != '\0') + if (p != NULL && *p != '\0') { ret = (a->compressor.write)(a, p, strlen(p)); + if (ret != ARCHIVE_OK) + return (ARCHIVE_FATAL); + pad = 0x3 & -strlen(p); + ret = (a->compressor.write)(a, "\0\0\0", pad); + } return (ret); } diff --git a/lib/libarchive/test/test_write_format_cpio_newc.c b/lib/libarchive/test/test_write_format_cpio_newc.c index 733e4ab26cd2..9b16e47cceac 100644 --- a/lib/libarchive/test/test_write_format_cpio_newc.c +++ b/lib/libarchive/test/test_write_format_cpio_newc.c @@ -68,6 +68,8 @@ DEFINE_TEST(test_write_format_cpio_newc) * Add various files to it. * TODO: Extend this to cover more filetypes. */ + + /* Regular file */ assert((entry = archive_entry_new()) != NULL); archive_entry_set_mtime(entry, 1, 10); archive_entry_set_pathname(entry, "file"); @@ -82,6 +84,7 @@ DEFINE_TEST(test_write_format_cpio_newc) archive_entry_free(entry); assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); + /* Directory */ assert((entry = archive_entry_new()) != NULL); archive_entry_set_mtime(entry, 2, 20); archive_entry_set_pathname(entry, "dir"); @@ -92,6 +95,22 @@ DEFINE_TEST(test_write_format_cpio_newc) archive_entry_free(entry); assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); + /* Symlink */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 3, 30); + archive_entry_set_pathname(entry, "lnk"); + archive_entry_set_mode(entry, S_IFLNK | 0664); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, 83); + archive_entry_set_gid(entry, 93); + archive_entry_set_dev(entry, 13); + archive_entry_set_ino(entry, 88); + archive_entry_set_nlink(entry, 1); + archive_entry_set_symlink(entry,"a"); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + + #if ARCHIVE_API_VERSION > 1 assert(0 == archive_write_finish(a)); #else @@ -122,7 +141,7 @@ DEFINE_TEST(test_write_format_cpio_newc) assertEqualMem(e + 110, "file\0\0", 6); /* Name contents */ assertEqualMem(e + 116, "1234567890", 10); /* File body */ assertEqualMem(e + 126, "\0\0", 2); /* Pad to multiple of 4 */ - e += 128; + e += 128; /* Must be multiple of four here! */ /* Second entry is "dir" */ assert(is_hex(e, 110)); @@ -142,7 +161,27 @@ DEFINE_TEST(test_write_format_cpio_newc) assertEqualMem(e + 102, "00000000", 8); /* CRC */ assertEqualMem(e + 110, "dir\0", 4); /* name */ assertEqualMem(e + 114, "\0\0", 2); /* Pad to multiple of 4 */ - e += 116; + e += 116; /* Must be multiple of four here! */ + + /* Third entry is "lnk" */ + assert(is_hex(e, 110)); /* Entire header is hex digits. */ + assertEqualMem(e + 0, "070701", 6); /* Magic */ + assertEqualMem(e + 6, "00000058", 8); /* ino */ + assertEqualMem(e + 14, "0000a1b4", 8); /* Mode */ + assertEqualMem(e + 22, "00000053", 8); /* uid */ + assertEqualMem(e + 30, "0000005d", 8); /* gid */ + assertEqualMem(e + 38, "00000001", 8); /* nlink */ + assertEqualMem(e + 46, "00000003", 8); /* mtime */ + assertEqualMem(e + 54, "00000001", 8); /* File size */ + assertEqualMem(e + 62, "00000000", 8); /* devmajor */ + assertEqualMem(e + 70, "0000000d", 8); /* devminor */ + assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ + assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ + assertEqualMem(e + 94, "00000004", 8); /* Name size */ + assertEqualMem(e + 102, "00000000", 8); /* CRC */ + assertEqualMem(e + 110, "lnk\0\0\0", 6); /* Name contents */ + assertEqualMem(e + 116, "a\0\0\0", 4); /* File body + pad */ + e += 120; /* Must be multiple of four here! */ /* TODO: Verify other types of entries. */ @@ -164,7 +203,7 @@ DEFINE_TEST(test_write_format_cpio_newc) assertEqualMem(e + 102, "00000000", 8); /* CRC */ assertEqualMem(e + 110, "TRAILER!!!\0", 11); /* Name */ assertEqualMem(e + 121, "\0\0\0", 3); /* Pad to multiple of 4 bytes */ - e += 124; + e += 124; /* Must be multiple of four here! */ assertEqualInt(used, e - buff);