diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-09-10 18:05:54 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-09-10 18:05:54 +0000 |
commit | c0445100a7bbd2a4e4279482b02be15bf44c51f1 (patch) | |
tree | 999e30fb379384f86267d1746269cd9b79589061 /lib | |
parent | c0f53576aa5ac177315bef513e401b2e2bd90ed1 (diff) | |
download | FreeBSD-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.c | 23 |
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); } /* |