summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2005-09-10 18:05:54 +0000
committerkientzle <kientzle@FreeBSD.org>2005-09-10 18:05:54 +0000
commitc0445100a7bbd2a4e4279482b02be15bf44c51f1 (patch)
tree999e30fb379384f86267d1746269cd9b79589061 /lib
parentc0f53576aa5ac177315bef513e401b2e2bd90ed1 (diff)
downloadFreeBSD-src-c0445100a7bbd2a4e4279482b02be15bf44c51f1.zip
FreeBSD-src-c0445100a7bbd2a4e4279482b02be15bf44c51f1.tar.gz
Fix some errors in archive_read_data that caused failures in bsdtar's
pass-through filtering. Thanks to: Bjoern Koenigönig PR: bin/82878
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_read.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c
index 61a9661..7e81fb2 100644
--- a/lib/libarchive/archive_read.c
+++ b/lib/libarchive/archive_read.c
@@ -347,7 +347,6 @@ archive_read_header_position(struct archive *a)
ssize_t
archive_read_data(struct archive *a, void *buff, size_t s)
{
- off_t remaining;
char *dest;
size_t bytes_read;
size_t len;
@@ -364,26 +363,26 @@ archive_read_data(struct archive *a, void *buff, size_t s)
&a->read_data_offset);
if (r == ARCHIVE_EOF)
return (bytes_read);
- if (r != ARCHIVE_OK)
+ /*
+ * Error codes are all negative, so the status
+ * return here cannot be confused with a valid
+ * byte count. (ARCHIVE_OK is zero.)
+ */
+ if (r < ARCHIVE_OK)
return (r);
}
if (a->read_data_offset < a->read_data_output_offset) {
- remaining =
- a->read_data_output_offset - a->read_data_offset;
- if (remaining > (off_t)s)
- remaining = (off_t)s;
- len = (size_t)remaining;
- memset(dest, 0, len);
- a->read_data_output_offset += len;
- s -= len;
- bytes_read += len;
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encountered out-of-order sparse blocks");
+ return (ARCHIVE_RETRY);
} else {
len = a->read_data_remaining;
if (len > s)
len = s;
memcpy(dest, a->read_data_block, len);
s -= len;
+ a->read_data_block += len;
a->read_data_remaining -= len;
a->read_data_output_offset += len;
a->read_data_offset += len;
@@ -391,7 +390,7 @@ archive_read_data(struct archive *a, void *buff, size_t s)
bytes_read += len;
}
}
- return (ARCHIVE_OK);
+ return (bytes_read);
}
/*
OpenPOWER on IntegriCloud