diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-05-18 18:16:30 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-05-18 18:16:30 +0000 |
commit | a7d0d63b7f17ea9395e4bf846f7eb13136cdc98b (patch) | |
tree | deaad9374c8c563983fb7d47be14f072cfd4841e /lib/libarchive | |
parent | 1704e84abaedb4374c1b50dba87d22f85eae39f1 (diff) | |
download | FreeBSD-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.c | 20 |
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; |