Tighten up the heuristic that decides whether or not we should
obey or ignore the size field on a hardlink entry. In particular, if we're reading a non-POSIX archive, we should always ignore the size field. This should fix both the audio/xmcd port and the math/unixstat port. Thanks to: Pav Lucistnik for pointing these two ports out to me. MFC after: 7 days
This commit is contained in:
parent
104954fe06
commit
6f6dfc16c2
@ -943,30 +943,46 @@ header_common(struct archive_read *a, struct tar *tar,
|
|||||||
* A tricky point: Traditionally, tar readers have
|
* A tricky point: Traditionally, tar readers have
|
||||||
* ignored the size field when reading hardlink
|
* ignored the size field when reading hardlink
|
||||||
* entries, and some writers put non-zero sizes even
|
* entries, and some writers put non-zero sizes even
|
||||||
* though the body is empty. POSIX.1-2001 broke with
|
* though the body is empty. POSIX blessed this
|
||||||
* this tradition by permitting hardlink entries to
|
* convention in the 1988 standard, but broke with
|
||||||
* store valid bodies in pax interchange format, but
|
* this tradition in 2001 by permitting hardlink
|
||||||
* not in ustar format. Since there is no hard and
|
* entries to store valid bodies in pax interchange
|
||||||
* fast way to distinguish pax interchange from
|
* format, but not in ustar format. Since there is no
|
||||||
* earlier archives (the 'x' and 'g' entries are
|
* hard and fast way to distinguish pax interchange
|
||||||
* optional, after all), we need a heuristic. Here, I
|
* from earlier archives (the 'x' and 'g' entries are
|
||||||
* use the bid function to test whether or not there's
|
* optional, after all), we need a heuristic.
|
||||||
* a valid header following. Of course, if we know
|
|
||||||
* this is pax interchange format, then we must obey
|
|
||||||
* the size.
|
|
||||||
*
|
|
||||||
* This heuristic will only fail for a pax interchange
|
|
||||||
* archive that is storing hardlink bodies, no pax
|
|
||||||
* extended attribute entries have yet occurred, and
|
|
||||||
* we encounter a hardlink entry for a file that is
|
|
||||||
* itself an uncompressed tar archive.
|
|
||||||
*/
|
*/
|
||||||
if (archive_entry_size(entry) > 0 &&
|
if (archive_entry_size(entry) == 0) {
|
||||||
a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE &&
|
/* If the size is already zero, we're done. */
|
||||||
archive_read_format_tar_bid(a) > 50) {
|
} else if (a->archive.archive_format
|
||||||
|
== ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
|
||||||
|
/* Definitely pax extended; must obey hardlink size. */
|
||||||
|
} else if (a->archive.archive_format == ARCHIVE_FORMAT_TAR
|
||||||
|
|| a->archive.archive_format == ARCHIVE_FORMAT_TAR_GNUTAR)
|
||||||
|
{
|
||||||
|
/* Old-style or GNU tar: we must ignore the size. */
|
||||||
|
archive_entry_set_size(entry, 0);
|
||||||
|
tar->entry_bytes_remaining = 0;
|
||||||
|
} else if (archive_read_format_tar_bid(a) > 50) {
|
||||||
|
/*
|
||||||
|
* We don't know if it's pax: If the bid
|
||||||
|
* function sees a valid ustar header
|
||||||
|
* immediately following, then let's ignore
|
||||||
|
* the hardlink size.
|
||||||
|
*/
|
||||||
archive_entry_set_size(entry, 0);
|
archive_entry_set_size(entry, 0);
|
||||||
tar->entry_bytes_remaining = 0;
|
tar->entry_bytes_remaining = 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* TODO: There are still two cases I'd like to handle:
|
||||||
|
* = a ustar non-pax archive with a hardlink entry at
|
||||||
|
* end-of-archive. (Look for block of nulls following?)
|
||||||
|
* = a pax archive that has not seen any pax headers
|
||||||
|
* and has an entry which is a hardlink entry storing
|
||||||
|
* a body containing an uncompressed tar archive.
|
||||||
|
* The first is worth addressing; I don't see any reliable
|
||||||
|
* way to deal with the second possibility.
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
case '2': /* Symlink */
|
case '2': /* Symlink */
|
||||||
archive_entry_set_filetype(entry, AE_IFLNK);
|
archive_entry_set_filetype(entry, AE_IFLNK);
|
||||||
|
Loading…
Reference in New Issue
Block a user