mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-27 11:55:06 +00:00
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)
This commit is contained in:
parent
35e32fd8a3
commit
456db9b6db
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=130064
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user