summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2004-06-04 10:27:23 +0000
committerkientzle <kientzle@FreeBSD.org>2004-06-04 10:27:23 +0000
commitf3849cee68ad3fa07fde7469f9172f75f51c997f (patch)
tree3f41de746a88e6900833278d091fea166ea97d8c /lib
parent7fec1d493133d2b669b572d3dca639704968dd51 (diff)
downloadFreeBSD-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.c25
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);
}
OpenPOWER on IntegriCloud