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.
This commit is contained in:
parent
f7dd47a8d1
commit
6c1a87e738
@ -209,12 +209,12 @@ archive_read_format_tar_bid(struct archive *a)
|
|||||||
|
|
||||||
header = h;
|
header = h;
|
||||||
|
|
||||||
/* This distinguishes POSIX formats from GNU tar formats. */
|
/* Recognize POSIX formats. */
|
||||||
if ((memcmp(header->magic, "ustar\0", 6) == 0)
|
if ((memcmp(header->magic, "ustar\0", 6) == 0)
|
||||||
&&(memcmp(header->version, "00", 2)==0))
|
&&(memcmp(header->version, "00", 2)==0))
|
||||||
bid += 56;
|
bid += 56;
|
||||||
|
|
||||||
/* Recognize GNU tar format as well. */
|
/* Recognize GNU tar format. */
|
||||||
if ((memcmp(header->magic, "ustar ", 6) == 0)
|
if ((memcmp(header->magic, "ustar ", 6) == 0)
|
||||||
&&(memcmp(header->version, " \0", 2)==0))
|
&&(memcmp(header->version, " \0", 2)==0))
|
||||||
bid += 56;
|
bid += 56;
|
||||||
@ -593,6 +593,22 @@ header_common(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
|||||||
*/
|
*/
|
||||||
if (st->st_size > 0)
|
if (st->st_size > 0)
|
||||||
st->st_mode |= S_IFREG;
|
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;
|
break;
|
||||||
case '2': /* Symlink */
|
case '2': /* Symlink */
|
||||||
st->st_mode |= S_IFLNK;
|
st->st_mode |= S_IFLNK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user