summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2005-10-12 03:27:46 +0000
committerkientzle <kientzle@FreeBSD.org>2005-10-12 03:27:46 +0000
commitf86a60099feb5508e55a8a6dd7bbee4486be0a69 (patch)
treec996560371c10618fc827671f209428c09a251e2 /lib/libarchive
parent456d84d6658548ed57af32c0f24db36ad1e3865f (diff)
downloadFreeBSD-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')
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c26
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;
OpenPOWER on IntegriCloud