summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libarchive/archive_read.c40
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c28
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c10
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
OpenPOWER on IntegriCloud