diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-10-12 03:27:46 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-10-12 03:27:46 +0000 |
commit | f86a60099feb5508e55a8a6dd7bbee4486be0a69 (patch) | |
tree | c996560371c10618fc827671f209428c09a251e2 /lib/libarchive/archive_read_support_format_tar.c | |
parent | 456d84d6658548ed57af32c0f24db36ad1e3865f (diff) | |
download | FreeBSD-src-f86a60099feb5508e55a8a6dd7bbee4486be0a69.zip FreeBSD-src-f86a60099feb5508e55a8a6dd7bbee4486be0a69.tar.gz |
When reading GNU-style sparse archive entries, handle
the first sparse block correctly (we used to assume
that the first sparse block was always at offset zero).
Diffstat (limited to 'lib/libarchive/archive_read_support_format_tar.c')
-rw-r--r-- | lib/libarchive/archive_read_support_format_tar.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index e854c70..21ae3d3 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -450,24 +450,34 @@ archive_read_format_tar_read_data(struct archive *a, struct sparse_block *p; tar = *(a->pformat_data); - if (tar->entry_bytes_remaining > 0) { - bytes_read = (a->compression_read_ahead)(a, buff, 1); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - if (bytes_read > tar->entry_bytes_remaining) - bytes_read = tar->entry_bytes_remaining; + if (tar->sparse_list != NULL) { + /* Remove exhausted entries from sparse list. */ while (tar->sparse_list != NULL && tar->sparse_list->remaining == 0) { p = tar->sparse_list; tar->sparse_list = p->next; free(p); - if (tar->sparse_list != NULL) - tar->entry_offset = tar->sparse_list->offset; } + if (tar->sparse_list == NULL) { + /* We exhausted the entire sparse list. */ + tar->entry_bytes_remaining = 0; + } + } + + if (tar->entry_bytes_remaining > 0) { + bytes_read = (a->compression_read_ahead)(a, buff, 1); + if (bytes_read <= 0) + return (ARCHIVE_FATAL); + if (bytes_read > tar->entry_bytes_remaining) + bytes_read = tar->entry_bytes_remaining; if (tar->sparse_list != NULL) { + /* Don't read more than is available in the + * current sparse block. */ if (tar->sparse_list->remaining < bytes_read) bytes_read = tar->sparse_list->remaining; + tar->entry_offset = tar->sparse_list->offset; tar->sparse_list->remaining -= bytes_read; + tar->sparse_list->offset += bytes_read; } *size = bytes_read; *offset = tar->entry_offset; |