diff options
-rw-r--r-- | lib/libarchive/archive_read.c | 40 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_iso9660.c | 28 | ||||
-rw-r--r-- | lib/libarchive/archive_read_support_format_tar.c | 10 |
3 files changed, 44 insertions, 34 deletions
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index c92b20c..06a4e8c 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); static int choose_decompressor(struct archive_read *, const void*, size_t); static int choose_format(struct archive_read *); +static off_t dummy_skip(struct archive_read *, off_t); /* * Allocate, initialize and return a struct archive object. @@ -191,6 +192,13 @@ archive_read_open2(struct archive *_a, void *client_data, if (e == ARCHIVE_OK) a->archive.state = ARCHIVE_STATE_HEADER; + /* + * If the decompressor didn't register a skip function, provide a + * dummy compression-layer skip function. + */ + if (a->compression_skip == NULL) + a->compression_skip = dummy_skip; + return (e); } @@ -244,6 +252,38 @@ choose_decompressor(struct archive_read *a, } /* + * Dummy skip function, for use if the compression layer doesn't provide + * one: This code just reads data and discards it. + */ +static off_t +dummy_skip(struct archive_read * a, off_t request) +{ + const void * dummy_buffer; + ssize_t bytes_read; + off_t bytes_skipped; + + for (bytes_skipped = 0; request > 0;) { + bytes_read = (a->compression_read_ahead)(a, &dummy_buffer, 1); + if (bytes_read < 0) + return (bytes_read); + if (bytes_read == 0) { + /* Premature EOF. */ + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Truncated input file (need to skip %jd bytes)", + (intmax_t)request); + return (ARCHIVE_FATAL); + } + if (bytes_read > request) + bytes_read = request; + (a->compression_read_consume)(a, bytes_read); + request -= bytes_read; + bytes_skipped += bytes_read; + } + + return (bytes_skipped); +} + +/* * Read header of next entry. */ int diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c index f115b0e..c892f72 100644 --- a/lib/libarchive/archive_read_support_format_iso9660.c +++ b/lib/libarchive/archive_read_support_format_iso9660.c @@ -917,33 +917,13 @@ fprintf(stderr, " *** Discarding CE data.\n"); offset = file->offset; /* Seek forward to the start of the entry. */ - /* Use fast compression_skip if it's available. */ - if (iso9660->current_position < offset - && a->compression_skip != NULL) { + if (iso9660->current_position < offset) { off_t step = offset - iso9660->current_position; off_t bytes_read; bytes_read = (a->compression_skip)(a, step); - iso9660->current_position += bytes_read; - } - - /* Use a series of reads if compression_skip didn't - * get us all the way there. */ - while (iso9660->current_position < offset) { - ssize_t step = offset - iso9660->current_position; - ssize_t bytes_read; - const void *buff; - - if (step > iso9660->logical_block_size) - step = iso9660->logical_block_size; - bytes_read = (a->compression_read_ahead)(a, &buff, step); - if (bytes_read <= 0) { - release_file(iso9660, file); - return (ARCHIVE_FATAL); - } - if (bytes_read > step) - bytes_read = step; - iso9660->current_position += bytes_read; - (a->compression_read_consume)(a, bytes_read); + if (bytes_read < 0) + return (bytes_read); + iso9660->current_position = offset; } /* We found body of file; handle it now. */ diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index 8aa5a38..3c24733 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -546,18 +546,8 @@ archive_read_format_tar_skip(struct archive_read *a) off_t bytes_skipped; struct tar* tar; struct sparse_block *p; - int r = ARCHIVE_OK; - const void *b; /* dummy variables */ - size_t s; - off_t o; - tar = (struct tar *)*(a->pformat_data); - if (a->compression_skip == NULL) { - while (r == ARCHIVE_OK) - r = archive_read_format_tar_read_data(a, &b, &s, &o); - return (r); - } /* * Compression layer skip functions are required to either skip the |