diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-06-04 10:27:23 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-06-04 10:27:23 +0000 |
commit | f3849cee68ad3fa07fde7469f9172f75f51c997f (patch) | |
tree | 3f41de746a88e6900833278d091fea166ea97d8c /lib | |
parent | 7fec1d493133d2b669b572d3dca639704968dd51 (diff) | |
download | FreeBSD-src-f3849cee68ad3fa07fde7469f9172f75f51c997f.zip FreeBSD-src-f3849cee68ad3fa07fde7469f9172f75f51c997f.tar.gz |
When we go to read the next tar header, if we get zero bytes, accept
that as end-of-archive. Otherwise, a short read at this point
generates an error. This accomodates broken tar writers (such as the
one apparently in use at AT&T Labs) that don't even write a single
end-of-archive block.
Note that both star and pdtar behave this way as well.
In contrast, gtar doesn't complain in either case, and as a
result, will generate no warning for a lot of trashed archives.
Pointed out by: shells/ksh93 port (Thanks to Kris Kennaway)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_read_support_format_tar.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index db7c28b..1617b0f 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -201,8 +201,19 @@ archive_read_format_tar_bid(struct archive *a) /* Now let's look at the actual header and see if it matches. */ bytes_read = (a->compression_read_ahead)(a, &h, 512); - if (bytes_read < 512) + if (bytes_read < 0) return (ARCHIVE_FATAL); + if (bytes_read == 0 && bid > 0) { + /* An archive without a proper end-of-archive marker. */ + /* Hold our nose and bid 1 anyway. */ + return (1); + } + if (bytes_read < 512) { + if (bid > 0) + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "Truncated tar archive"); + return (ARCHIVE_FATAL); + } /* If it's an end-of-archive mark, we can handle it. */ if ((*(const char *)h) == 0 && archive_block_is_null(h)) @@ -325,13 +336,21 @@ tar_read_header(struct archive *a, struct tar *tar, /* Read 512-byte header record */ bytes = (a->compression_read_ahead)(a, &h, 512); if (bytes < 512) { - /* TODO: Set error values */ - return (-1); + /* + * If we're here, it's becase the _bid function accepted + * this file. So just call a short read end-of-archive + * and be done with it. + */ + return (ARCHIVE_EOF); } (a->compression_read_consume)(a, 512); /* Check for end-of-archive mark. */ if (((*(const char *)h)==0) && archive_block_is_null(h)) { + /* Try to consume a second all-null record, as well. */ + bytes = (a->compression_read_ahead)(a, &h, 512); + if (bytes > 0) + (a->compression_read_consume)(a, bytes); archive_set_error(a, 0, NULL); return (ARCHIVE_EOF); } |