diff --git a/lib/libarchive/archive_write_set_format_cpio.c b/lib/libarchive/archive_write_set_format_cpio.c index 80dbf3869a72..ba23f3218055 100644 --- a/lib/libarchive/archive_write_set_format_cpio.c +++ b/lib/libarchive/archive_write_set_format_cpio.c @@ -142,12 +142,17 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) format_octal(archive_entry_mtime(entry), &h.c_mtime, sizeof(h.c_mtime)); format_octal(pathlength, &h.c_namesize, sizeof(h.c_namesize)); + /* Non-regular files don't store bodies. */ + if (archive_entry_filetype(entry) != AE_IFREG) + archive_entry_set_size(entry, 0); + /* Symlinks get the link written as the body of the entry. */ p = archive_entry_symlink(entry); if (p != NULL && *p != '\0') format_octal(strlen(p), &h.c_filesize, sizeof(h.c_filesize)); else - format_octal(archive_entry_size(entry), &h.c_filesize, sizeof(h.c_filesize)); + format_octal(archive_entry_size(entry), + &h.c_filesize, sizeof(h.c_filesize)); ret = (a->compressor.write)(a, &h, sizeof(h)); if (ret != ARCHIVE_OK) diff --git a/lib/libarchive/archive_write_set_format_cpio_newc.c b/lib/libarchive/archive_write_set_format_cpio_newc.c index b58559767d1a..37dd35af6313 100644 --- a/lib/libarchive/archive_write_set_format_cpio_newc.c +++ b/lib/libarchive/archive_write_set_format_cpio_newc.c @@ -148,12 +148,17 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry) format_hex(pathlength, &h.c_namesize, sizeof(h.c_namesize)); format_hex(0, &h.c_checksum, sizeof(h.c_checksum)); + /* Non-regular files don't store bodies. */ + if (archive_entry_filetype(entry) != AE_IFREG) + archive_entry_set_size(entry, 0); + /* Symlinks get the link written as the body of the entry. */ p = archive_entry_symlink(entry); if (p != NULL && *p != '\0') format_hex(strlen(p), &h.c_filesize, sizeof(h.c_filesize)); else - format_hex(archive_entry_size(entry), &h.c_filesize, sizeof(h.c_filesize)); + format_hex(archive_entry_size(entry), + &h.c_filesize, sizeof(h.c_filesize)); ret = (a->compressor.write)(a, &h, sizeof(h)); if (ret != ARCHIVE_OK) diff --git a/lib/libarchive/test/test_write_format_cpio.c b/lib/libarchive/test/test_write_format_cpio.c index 2ea40a36b445..886942ebd40e 100644 --- a/lib/libarchive/test/test_write_format_cpio.c +++ b/lib/libarchive/test/test_write_format_cpio.c @@ -66,6 +66,21 @@ test_format(int (*set_format)(struct archive *)) archive_entry_free(ae); assertA(8 == archive_write_data(a, "12345678", 9)); + /* + * Write a directory to it. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_mtime(ae, 11, 110); + archive_entry_copy_pathname(ae, "dir"); + archive_entry_set_mode(ae, S_IFDIR | 0755); + archive_entry_set_size(ae, 512); + + assertA(0 == archive_write_header(a, ae)); + assertEqualInt(0, archive_entry_size(ae)); + archive_entry_free(ae); + assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); + + /* Close out the archive. */ assertA(0 == archive_write_close(a)); #if ARCHIVE_API_VERSION > 1 @@ -95,8 +110,21 @@ test_format(int (*set_format)(struct archive *)) assertA(8 == archive_read_data(a, filedata, 10)); assert(0 == memcmp(filedata, "12345678", 8)); + /* + * Read the dir entry back. + */ + assertA(0 == archive_read_next_header(a, &ae)); + assert(11 == archive_entry_mtime(ae)); + assert(0 == archive_entry_mtime_nsec(ae)); + assert(0 == archive_entry_atime(ae)); + assert(0 == archive_entry_ctime(ae)); + assertEqualString("dir", archive_entry_pathname(ae)); + assert((S_IFDIR | 0755) == archive_entry_mode(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); + /* Verify the end of the archive. */ - assert(1 == archive_read_next_header(a, &ae)); + assertEqualIntA(a, 1, archive_read_next_header(a, &ae)); assert(0 == archive_read_close(a)); #if ARCHIVE_API_VERSION > 1 assert(0 == archive_read_finish(a));