Correct the cpio writers to not accept data for non-regular files.
In particular, the previous code led to archives that had non-empty bodies following directory entries. Not a fatal problem, as bsdtar and GNU cpio are both happy to just skip this bogus data, but it still shouldn't be there. MFC after: 3 days
This commit is contained in:
parent
7f13779429
commit
c2c3c21fbd
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user