summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2004-05-18 18:16:30 +0000
committerkientzle <kientzle@FreeBSD.org>2004-05-18 18:16:30 +0000
commita7d0d63b7f17ea9395e4bf846f7eb13136cdc98b (patch)
treedeaad9374c8c563983fb7d47be14f072cfd4841e /lib/libarchive
parent1704e84abaedb4374c1b50dba87d22f85eae39f1 (diff)
downloadFreeBSD-src-a7d0d63b7f17ea9395e4bf846f7eb13136cdc98b.zip
FreeBSD-src-a7d0d63b7f17ea9395e4bf846f7eb13136cdc98b.tar.gz
Be smarter about hardlink sizes: some tar programs write
a non-zero size but no body, some write a non-zero size and include a body. To distinguish these cases, look for a valid tar header immediately following a hardlink header with non-zero size.
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c
index f41e37d..468de5a 100644
--- a/lib/libarchive/archive_read_support_format_tar.c
+++ b/lib/libarchive/archive_read_support_format_tar.c
@@ -209,12 +209,12 @@ archive_read_format_tar_bid(struct archive *a)
header = h;
- /* This distinguishes POSIX formats from GNU tar formats. */
+ /* Recognize POSIX formats. */
if ((memcmp(header->magic, "ustar\0", 6) == 0)
&&(memcmp(header->version, "00", 2)==0))
bid += 56;
- /* Recognize GNU tar format as well. */
+ /* Recognize GNU tar format. */
if ((memcmp(header->magic, "ustar ", 6) == 0)
&&(memcmp(header->version, " \0", 2)==0))
bid += 56;
@@ -593,6 +593,22 @@ header_common(struct archive *a, struct tar *tar, struct archive_entry *entry,
*/
if (st->st_size > 0)
st->st_mode |= S_IFREG;
+ /*
+ * A tricky point: Traditionally, tar programs have
+ * ignored the size field when reading hardlink
+ * entries. As a result, some programs write non-zero
+ * sizes, even though the body is empty and expect the
+ * reader to ignore that. POSIX.1-2001 broke this by
+ * permitting hardlink entries to store valid bodies
+ * in pax interchange format. Since there is no hard
+ * and fast way to distinguish pax interchange from
+ * earlier archives (the 'x' and 'g' entries are
+ * optional, after all), we need a heuristic. Here, I
+ * use the bid function to test whether or not there's
+ * a valid header following.
+ */
+ if (st->st_size > 0 && archive_read_format_tar_bid(a) > 50)
+ st->st_size = 0;
break;
case '2': /* Symlink */
st->st_mode |= S_IFLNK;
OpenPOWER on IntegriCloud