From: Tim Kientzle Date: Wed, 29 Oct 2008 22:07:37 +0000 (-0400) Subject: First step in transitioning the current decompression code to X-Git-Tag: v2.6.0~59 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9aeac49740d27af02c35231a5a89b397878cbc2c;p=thirdparty%2Flibarchive.git First step in transitioning the current decompression code to a more generic system of stackable stream transforms. In particular, I believe I've edited every place that called the decompressor directly to go through new __archive_read_ahead(), __archive_read_consume() and __archive_read_skip() functions, so the rest of the work here will not require any changes to the format handlers. I've also laid out the new types that will be needed for this. Next step is to rewrite the decompressors to the new interface, and overhaul the decompression auction to juggle generic "sources." Then I'll be able to consolidate reblocking into a single place; the transforms can emit arbitrary-sized blocks and the current decompress_none logic will be used to reblock as needed by the consumer format. The initial impetus for this was to simplify the decompressors by consolidating the reblocking logic. I recently came up with some other transforms I'd like to implement (including new decompressors, an encryption filter for secure backup, and uudecode handling to simplify test harnesses) that would also benefit from this. Eventually, I think I might be able to standardize the interface for new transforms enough to allow libarchive clients to register their own transforms complete with bidding logic (the old interface was too wired into libarchive internals for the API to be exported). In the very long term, this might divorce the transformation logic from the rest of libarchive enough to allow it to be packaged as an independent library. SVN-Revision: 234 --- diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index 327969f41..223d7679d 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -108,6 +108,32 @@ archive_read_open(struct archive *a, void *client_data, client_reader, NULL, client_closer); } +static ssize_t +client_read_proxy(struct archive_read_source *self, const void **buff) +{ + return (self->archive->client.reader)((struct archive *)self->archive, + self->data, buff); +} + +static int64_t +client_skip_proxy(struct archive_read_source *self, int64_t request) +{ + return (self->archive->client.skipper)((struct archive *)self->archive, + self->data, request); +} + +static ssize_t +client_close_proxy(struct archive_read_source *self) +{ + int r; + + r = (self->archive->client.closer)((struct archive *)self->archive, + self->data); + free(self); + return (r); +} + + int archive_read_open2(struct archive *_a, void *client_data, archive_open_callback *client_opener, @@ -120,7 +146,8 @@ archive_read_open2(struct archive *_a, void *client_data, ssize_t bytes_read; int e; - __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, "archive_read_open"); + __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, + "archive_read_open"); if (client_reader == NULL) __archive_errx(1, @@ -132,11 +159,11 @@ archive_read_open2(struct archive *_a, void *client_data, * (In particular, this helps ensure that the closer doesn't * get called more than once.) */ - a->client_opener = NULL; - a->client_reader = NULL; - a->client_skipper = NULL; - a->client_closer = NULL; - a->client_data = NULL; + a->client.opener = NULL; + a->client.reader = NULL; + a->client.skipper = NULL; + a->client.closer = NULL; + a->client.data = NULL; /* Open data source. */ if (client_opener != NULL) { @@ -161,11 +188,27 @@ archive_read_open2(struct archive *_a, void *client_data, } /* Now that the client callbacks have worked, remember them. */ - a->client_opener = client_opener; /* Do we need to remember this? */ - a->client_reader = client_reader; - a->client_skipper = client_skipper; - a->client_closer = client_closer; - a->client_data = client_data; + a->client.opener = client_opener; /* Do we need to remember this? */ + a->client.reader = client_reader; + a->client.skipper = client_skipper; + a->client.closer = client_closer; + a->client.data = client_data; + + { + struct archive_read_source *source; + + source = calloc(1, sizeof(*source)); + if (source == NULL) + return (ARCHIVE_FATAL); + source->reader = NULL; + source->source = NULL; + source->archive = a; + source->data = client_data; + source->read = client_read_proxy; + source->skip = client_skip_proxy; + source->close = client_close_proxy; + a->source = source; + } /* Select a decompression routine. */ choose_decompressor(a, buffer, (size_t)bytes_read); @@ -182,8 +225,8 @@ archive_read_open2(struct archive *_a, void *client_data, * If the decompressor didn't register a skip function, provide a * dummy compression-layer skip function. */ - if (a->decompressor->skip == NULL) - a->decompressor->skip = dummy_skip; + if (a->decompressor->skip2 == NULL) + a->decompressor->skip2 = dummy_skip; return (e); } @@ -254,7 +297,7 @@ dummy_skip(struct archive_read * a, off_t request) off_t bytes_skipped; for (bytes_skipped = 0; request > 0;) { - bytes_read = (a->decompressor->read_ahead)(a, &dummy_buffer, 1); + bytes_read = (a->decompressor->read_ahead2)(a, &dummy_buffer, 1); if (bytes_read < 0) return (bytes_read); if (bytes_read == 0) { @@ -266,7 +309,7 @@ dummy_skip(struct archive_read * a, off_t request) } if (bytes_read > request) bytes_read = (ssize_t)request; - (a->decompressor->consume)(a, (size_t)bytes_read); + (a->decompressor->consume2)(a, (size_t)bytes_read); request -= bytes_read; bytes_skipped += bytes_read; } @@ -609,8 +652,8 @@ archive_read_close(struct archive *_a) } /* Close the client stream. */ - if (a->client_closer != NULL) { - r1 = ((a->client_closer)(&a->archive, a->client_data)); + if (a->client.closer != NULL) { + r1 = ((a->client.closer)(&a->archive, a->client.data)); if (r1 < r) r = r1; } @@ -729,11 +772,29 @@ __archive_read_register_compression(struct archive_read *a, /* used internally to simplify read-ahead */ const void * -__archive_read_ahead(struct archive_read *a, size_t len) +__archive_read_ahead(struct archive_read *a, size_t len, size_t *avail) { + ssize_t av; const void *h; - if ((a->decompressor->read_ahead)(a, &h, len) < (ssize_t)len) + av = (a->decompressor->read_ahead2)(a, &h, len); + /* Return # bytes avail (also error code) regardless. */ + if (avail != NULL && av >= 0) + *avail = av; + /* If it was a short read, return NULL. */ + if (av < (ssize_t)len) return (NULL); return (h); } + +ssize_t +__archive_read_consume(struct archive_read *a, size_t s) +{ + return (a->decompressor->consume2)(a, s); +} + +int64_t +__archive_read_skip(struct archive_read *a, uint64_t s) +{ + return (a->decompressor->skip2)(a, s); +} diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h index af25b043e..efa348242 100644 --- a/libarchive/archive_read_private.h +++ b/libarchive/archive_read_private.h @@ -32,6 +32,74 @@ #include "archive_string.h" #include "archive_private.h" +struct archive_read; +struct archive_reader; +struct archive_read_source; + +/* + * A "reader" knows how to provide blocks. That can include something + * that reads blocks from disk or socket or a transformation layer + * that reads blocks from another source and transforms them. This + * includes decompression and decryption filters. + * + * How bidding works: + * * The bid manager reads the first block from the current source. + * * It shows that block to each registered bidder. + * * The winning bidder is initialized (with the block and information + * about the source) + * * The winning bidder becomes the new source and the process repeats + * This ends only when no reader provides a non-zero bid. + */ +struct archive_reader { + /* Configuration data for the reader. */ + void *data; + /* Bidder is handed the initial block from its source. */ + int (*bid)(const void *buff, size_t); + /* Init() is given the archive, upstream source, and the initial + * block above. It returns a populated source structure. */ + struct archive_read_source *(*init)(struct archive_read *, + struct archive_read_source *source, const void *, size_t); + /* Release the reader and any configuration data it allocated. */ + void (*free)(struct archive_reader *); +}; + +/* + * A "source" is an instance of a reader. This structure is + * allocated and initialized by the init() method of a reader + * above. + */ +struct archive_read_source { + /* Essentially all sources will need these values, so + * just declare them here. */ + struct archive_reader *reader; /* Reader that I'm an instance of. */ + struct archive_read_source *source; /* Who I get blocks from. */ + struct archive_read *archive; /* associated archive. */ + /* Return next block. */ + ssize_t (*read)(struct archive_read_source *, const void **); + /* Skip forward this many bytes. */ + int64_t (*skip)(struct archive_read_source *self, int64_t request); + /* Close (recursively) and free(self). */ + int (*close)(struct archive_read_source *self); + /* My private data. */ + void *data; +}; + +/* + * The client source is almost the same as an internal source. + * + * TODO: Make archive_read_source and archive_read_client identical so + * that users of the library can easily register their own + * transformation filters. This will probably break the API/ABI and + * so should be deferred until libarchive 3.0. + */ +struct archive_read_client { + archive_open_callback *opener; + archive_read_callback *reader; + archive_skip_callback *skipper; + archive_close_callback *closer; + void *data; +}; + struct archive_read { struct archive archive; @@ -50,12 +118,14 @@ struct archive_read { off_t read_data_output_offset; size_t read_data_remaining; - /* Callbacks to open/read/write/close archive stream. */ - archive_open_callback *client_opener; - archive_read_callback *client_reader; - archive_skip_callback *client_skipper; - archive_close_callback *client_closer; - void *client_data; + /* Callbacks to open/read/write/close client archive stream. */ + struct archive_read_client client; + + /* Registered readers. */ + struct archive_reader readers[8]; + + /* Source */ + struct archive_read_source *source; /* File offset of beginning of most recently-read header. */ off_t header_position; @@ -82,10 +152,10 @@ struct archive_read { int (*init)(struct archive_read *, const void *buff, size_t); int (*finish)(struct archive_read *); - ssize_t (*read_ahead)(struct archive_read *, + ssize_t (*read_ahead2)(struct archive_read *, const void **, size_t); - ssize_t (*consume)(struct archive_read *, size_t); - off_t (*skip)(struct archive_read *, off_t); + ssize_t (*consume2)(struct archive_read *, size_t); + off_t (*skip2)(struct archive_read *, off_t); } decompressors[5]; /* Pointer to current decompressor. */ @@ -128,8 +198,10 @@ struct decompressor_t *__archive_read_register_compression(struct archive_read *a, int (*bid)(const void *, size_t), int (*init)(struct archive_read *, const void *, size_t)); - const void - *__archive_read_ahead(struct archive_read *, size_t); - + *__archive_read_ahead(struct archive_read *, size_t, size_t *); +ssize_t + __archive_read_consume(struct archive_read *, size_t); +int64_t + __archive_read_skip(struct archive_read *, uint64_t); #endif diff --git a/libarchive/archive_read_support_compression_bzip2.c b/libarchive/archive_read_support_compression_bzip2.c index 824b0cdeb..279c3755a 100644 --- a/libarchive/archive_read_support_compression_bzip2.c +++ b/libarchive/archive_read_support_compression_bzip2.c @@ -209,9 +209,9 @@ init(struct archive_read *a, const void *buff, size_t n) state->stream.next_in = (char *)(uintptr_t)(const void *)buff; state->stream.avail_in = n; - a->decompressor->read_ahead = read_ahead; - a->decompressor->consume = read_consume; - a->decompressor->skip = NULL; /* not supported */ + a->decompressor->read_ahead2 = read_ahead; + a->decompressor->consume2 = read_consume; + a->decompressor->skip2 = NULL; /* not supported */ a->decompressor->finish = finish; /* Initialize compression library. */ @@ -272,13 +272,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min) int ret; state = (struct private_data *)a->decompressor->data; - if (!a->client_reader) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "No read callback is registered? " - "This is probably an internal programming error."); - return (ARCHIVE_FATAL); - } - read_avail = state->stream.next_out - state->read_next; if (read_avail + state->stream.avail_out < min) { @@ -369,8 +362,7 @@ drive_decompressor(struct archive_read *a, struct private_data *state) for (;;) { if (state->stream.avail_in == 0) { read_buf = state->stream.next_in; - ret = (a->client_reader)(&a->archive, a->client_data, - &read_buf); + ret = (a->source->read)(a->source, &read_buf); state->stream.next_in = (void *)(uintptr_t)read_buf; if (ret < 0) { /* diff --git a/libarchive/archive_read_support_compression_compress.c b/libarchive/archive_read_support_compression_compress.c index 050099b21..e1c9896dc 100644 --- a/libarchive/archive_read_support_compression_compress.c +++ b/libarchive/archive_read_support_compression_compress.c @@ -199,9 +199,9 @@ init(struct archive_read *a, const void *buff, size_t n) a->archive.compression_code = ARCHIVE_COMPRESSION_COMPRESS; a->archive.compression_name = "compress (.Z)"; - a->decompressor->read_ahead = read_ahead; - a->decompressor->consume = read_consume; - a->decompressor->skip = NULL; /* not supported */ + a->decompressor->read_ahead2 = read_ahead; + a->decompressor->consume2 = read_consume; + a->decompressor->skip2 = NULL; /* not supported */ a->decompressor->finish = finish; state = (struct private_data *)malloc(sizeof(*state)); @@ -281,13 +281,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min) int ret; state = (struct private_data *)a->decompressor->data; - if (!a->client_reader) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "No read callback is registered? " - "This is probably an internal programming error."); - return (ARCHIVE_FATAL); - } - read_avail = state->next_out - state->read_next; if (read_avail < min && state->end_of_stream) { @@ -469,8 +462,7 @@ getbits(struct archive_read *a, struct private_data *state, int n) while (state->bits_avail < n) { if (state->avail_in <= 0) { read_buf = state->next_in; - ret = (a->client_reader)(&a->archive, a->client_data, - &read_buf); + ret = (a->source->read)(a->source, &read_buf); state->next_in = read_buf; if (ret < 0) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_compression_gzip.c b/libarchive/archive_read_support_compression_gzip.c index 2dac54da0..25f4a3254 100644 --- a/libarchive/archive_read_support_compression_gzip.c +++ b/libarchive/archive_read_support_compression_gzip.c @@ -201,9 +201,9 @@ init(struct archive_read *a, const void *buff, size_t n) state->stream.next_in = (Bytef *)(uintptr_t)(const void *)buff; state->stream.avail_in = n; - a->decompressor->read_ahead = read_ahead; - a->decompressor->consume = read_consume; - a->decompressor->skip = NULL; /* not supported */ + a->decompressor->read_ahead2 = read_ahead; + a->decompressor->consume2 = read_consume; + a->decompressor->skip2 = NULL; /* not supported */ a->decompressor->finish = finish; /* @@ -265,13 +265,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min) int ret; state = (struct private_data *)a->decompressor->data; - if (!a->client_reader) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "No read callback is registered? " - "This is probably an internal programming error."); - return (ARCHIVE_FATAL); - } - read_avail = state->stream.next_out - state->read_next; if (read_avail + state->stream.avail_out < min) { @@ -367,8 +360,7 @@ drive_decompressor(struct archive_read *a, struct private_data *state) for (;;) { if (state->stream.avail_in == 0) { read_buf = state->stream.next_in; - ret = (a->client_reader)(&a->archive, a->client_data, - &read_buf); + ret = (a->source->read)(a->source, &read_buf); state->stream.next_in = (unsigned char *)(uintptr_t)read_buf; if (ret < 0) { /* diff --git a/libarchive/archive_read_support_compression_none.c b/libarchive/archive_read_support_compression_none.c index 1ee38f64c..2c5c987c0 100644 --- a/libarchive/archive_read_support_compression_none.c +++ b/libarchive/archive_read_support_compression_none.c @@ -130,9 +130,9 @@ archive_decompressor_none_init(struct archive_read *a, const void *buff, size_t state->client_avail = state->client_total; a->decompressor->data = state; - a->decompressor->read_ahead = archive_decompressor_none_read_ahead; - a->decompressor->consume = archive_decompressor_none_read_consume; - a->decompressor->skip = archive_decompressor_none_skip; + a->decompressor->read_ahead2 = archive_decompressor_none_read_ahead; + a->decompressor->consume2 = archive_decompressor_none_read_consume; + a->decompressor->skip2 = archive_decompressor_none_skip; a->decompressor->finish = archive_decompressor_none_finish; return (ARCHIVE_OK); @@ -205,8 +205,8 @@ archive_decompressor_none_read_ahead(struct archive_read *a, const void **buff, /* TODO: Change this to return(0) consistent * with new eof handling commented below. */ } - bytes_read = (a->client_reader)(&a->archive, - a->client_data, &state->client_buff); + bytes_read = (a->source->read)(a->source, + &state->client_buff); if (bytes_read < 0) { /* Read error. */ state->client_total = state->client_avail = 0; state->client_next = state->client_buff = NULL; @@ -354,12 +354,11 @@ archive_decompressor_none_skip(struct archive_read *a, off_t request) * If a client_skipper was provided, try that first. */ #if ARCHIVE_API_VERSION < 2 - if ((a->client_skipper != NULL) && (request < SSIZE_MAX)) { + if ((a->source->skip != NULL) && (request < SSIZE_MAX)) { #else - if (a->client_skipper != NULL) { + if (a->source->skip != NULL) { #endif - bytes_skipped = (a->client_skipper)(&a->archive, - a->client_data, request); + bytes_skipped = (a->source->skip)(a->source, request); if (bytes_skipped < 0) { /* error */ state->client_total = state->client_avail = 0; state->client_next = state->client_buff = NULL; diff --git a/libarchive/archive_read_support_compression_program.c b/libarchive/archive_read_support_compression_program.c index 7b54d1ead..ca35125b1 100644 --- a/libarchive/archive_read_support_compression_program.c +++ b/libarchive/archive_read_support_compression_program.c @@ -161,8 +161,7 @@ restart_read: if (state->child_in_buf_avail == 0) { child_buf = state->child_in_buf; - ret = (a->client_reader)(&a->archive, - a->client_data,&child_buf); + ret = (a->source->read)(a->source, &child_buf); state->child_in_buf = (const char *)child_buf; if (ret < 0) { @@ -255,9 +254,9 @@ archive_decompressor_program_init(struct archive_read *a, const void *buff, size } a->decompressor->data = state; - a->decompressor->read_ahead = archive_decompressor_program_read_ahead; - a->decompressor->consume = archive_decompressor_program_read_consume; - a->decompressor->skip = NULL; + a->decompressor->read_ahead2 = archive_decompressor_program_read_ahead; + a->decompressor->consume2 = archive_decompressor_program_read_consume; + a->decompressor->skip2 = NULL; a->decompressor->finish = archive_decompressor_program_finish; /* XXX Check that we can read at least one byte? */ diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c index baf80bd62..a91b29850 100644 --- a/libarchive/archive_read_support_format_ar.c +++ b/libarchive/archive_read_support_format_ar.c @@ -135,7 +135,6 @@ static int archive_read_format_ar_bid(struct archive_read *a) { struct ar *ar; - ssize_t bytes_read; const void *h; if (a->archive.archive_format != 0 && @@ -149,8 +148,7 @@ archive_read_format_ar_bid(struct archive_read *a) * Verify the 8-byte file signature. * TODO: Do we need to check more than this? */ - bytes_read = (a->decompressor->read_ahead)(a, &h, 8); - if (bytes_read < 8) + if ((h = __archive_read_ahead(a, 8, NULL)) == NULL) return (-1); if (strncmp((const char*)h, "!\n", 8) == 0) { return (64); @@ -166,7 +164,7 @@ archive_read_format_ar_read_header(struct archive_read *a, struct ar *ar; uint64_t number; /* Used to hold parsed numbers before validation. */ ssize_t bytes_read; - size_t bsd_name_length, entry_size, s; + size_t bsd_name_length, entry_size; char *p, *st; const void *b; const char *h; @@ -179,18 +177,16 @@ archive_read_format_ar_read_header(struct archive_read *a, * We are now at the beginning of the archive, * so we need first consume the ar global header. */ - (a->decompressor->consume)(a, 8); + __archive_read_consume(a, 8); /* Set a default format code for now. */ a->archive.archive_format = ARCHIVE_FORMAT_AR; } /* Read the header for the next file entry. */ - bytes_read = (a->decompressor->read_ahead)(a, &b, 60); - if (bytes_read < 60) { + if ((b = __archive_read_ahead(a, 60, &bytes_read)) == NULL) /* Broken header. */ return (ARCHIVE_EOF); - } - (a->decompressor->consume)(a, 60); + __archive_read_consume(a, 60); h = (const char *)b; /* Verify the magic signature on the file header. */ @@ -296,16 +292,10 @@ archive_read_format_ar_read_header(struct archive_read *a, } ar->strtab = st; ar->strtab_size = entry_size; - for (s = entry_size; s > 0; s -= bytes_read) { - bytes_read = (a->decompressor->read_ahead)(a, &b, s); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - if (bytes_read > (ssize_t)s) - bytes_read = s; - memcpy(st, b, bytes_read); - st += bytes_read; - (a->decompressor->consume)(a, bytes_read); - } + if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL) + return (ARCHIVE_FATAL); + memcpy(st, b, entry_size); + __archive_read_consume(a, entry_size); /* All contents are consumed. */ ar->entry_bytes_remaining = 0; archive_entry_set_size(entry, ar->entry_bytes_remaining); @@ -365,15 +355,12 @@ archive_read_format_ar_read_header(struct archive_read *a, archive_entry_set_size(entry, ar->entry_bytes_remaining); /* Read the long name into memory. */ - bytes_read = (a->decompressor->read_ahead)(a, &b, bsd_name_length); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - if ((size_t)bytes_read < bsd_name_length) { + if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Truncated input file"); return (ARCHIVE_FATAL); } - (a->decompressor->consume)(a, bsd_name_length); + __archive_read_consume(a, bsd_name_length); /* Store it in the entry. */ p = (char *)malloc(bsd_name_length + 1); @@ -453,7 +440,7 @@ archive_read_format_ar_read_data(struct archive_read *a, ar = (struct ar *)(a->format->data); if (ar->entry_bytes_remaining > 0) { - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read == 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Truncated ar archive"); @@ -467,16 +454,16 @@ archive_read_format_ar_read_data(struct archive_read *a, *offset = ar->entry_offset; ar->entry_offset += bytes_read; ar->entry_bytes_remaining -= bytes_read; - (a->decompressor->consume)(a, (size_t)bytes_read); + __archive_read_consume(a, (size_t)bytes_read); return (ARCHIVE_OK); } else { while (ar->entry_padding > 0) { - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0) return (ARCHIVE_FATAL); if (bytes_read > ar->entry_padding) bytes_read = (ssize_t)ar->entry_padding; - (a->decompressor->consume)(a, (size_t)bytes_read); + __archive_read_consume(a, (size_t)bytes_read); ar->entry_padding -= bytes_read; } *buff = NULL; @@ -491,20 +478,11 @@ archive_read_format_ar_skip(struct archive_read *a) { off_t bytes_skipped; struct ar* ar; - int r = ARCHIVE_OK; - const void *b; /* Dummy variables */ - size_t s; - off_t o; ar = (struct ar *)(a->format->data); - if (a->decompressor->skip == NULL) { - while (r == ARCHIVE_OK) - r = archive_read_format_ar_read_data(a, &b, &s, &o); - return (r); - } - bytes_skipped = (a->decompressor->skip)(a, ar->entry_bytes_remaining + - ar->entry_padding); + bytes_skipped = __archive_read_skip(a, + ar->entry_bytes_remaining + ar->entry_padding); if (bytes_skipped < 0) return (ARCHIVE_FATAL); diff --git a/libarchive/archive_read_support_format_cpio.c b/libarchive/archive_read_support_format_cpio.c index 3734b3863..9c3f2944b 100644 --- a/libarchive/archive_read_support_format_cpio.c +++ b/libarchive/archive_read_support_format_cpio.c @@ -165,7 +165,6 @@ archive_read_support_format_cpio(struct archive *_a) static int archive_read_format_cpio_bid(struct archive_read *a) { - int bytes_read; const void *h; const unsigned char *p; struct cpio *cpio; @@ -173,11 +172,7 @@ archive_read_format_cpio_bid(struct archive_read *a) cpio = (struct cpio *)(a->format->data); - bytes_read = (a->decompressor->read_ahead)(a, &h, 6); - /* Convert error code into error return. */ - if (bytes_read < 0) - return ((int)bytes_read); - if (bytes_read < 6) + if ((h = __archive_read_ahead(a, 6, NULL)) == NULL) return (-1); p = (const unsigned char *)h; @@ -228,7 +223,6 @@ archive_read_format_cpio_read_header(struct archive_read *a, struct archive_entry *entry) { struct cpio *cpio; - size_t bytes; const void *h; size_t namelength; size_t name_pad; @@ -241,21 +235,20 @@ archive_read_format_cpio_read_header(struct archive_read *a, return (r); /* Read name from buffer. */ - bytes = (a->decompressor->read_ahead)(a, &h, namelength + name_pad); - if (bytes < namelength + name_pad) + h = __archive_read_ahead(a, namelength + name_pad, NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, namelength + name_pad); + __archive_read_consume(a, namelength + name_pad); archive_strncpy(&cpio->entry_name, (const char *)h, namelength); archive_entry_set_pathname(entry, cpio->entry_name.s); cpio->entry_offset = 0; /* If this is a symlink, read the link contents. */ if (archive_entry_filetype(entry) == AE_IFLNK) { - bytes = (a->decompressor->read_ahead)(a, &h, - cpio->entry_bytes_remaining); - if ((off_t)bytes < cpio->entry_bytes_remaining) + h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, cpio->entry_bytes_remaining); + __archive_read_consume(a, cpio->entry_bytes_remaining); archive_strncpy(&cpio->entry_linkname, (const char *)h, cpio->entry_bytes_remaining); archive_entry_set_symlink(entry, cpio->entry_linkname.s); @@ -284,7 +277,7 @@ archive_read_format_cpio_read_data(struct archive_read *a, cpio = (struct cpio *)(a->format->data); if (cpio->entry_bytes_remaining > 0) { - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0) return (ARCHIVE_FATAL); if (bytes_read > cpio->entry_bytes_remaining) @@ -293,16 +286,16 @@ archive_read_format_cpio_read_data(struct archive_read *a, *offset = cpio->entry_offset; cpio->entry_offset += bytes_read; cpio->entry_bytes_remaining -= bytes_read; - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); return (ARCHIVE_OK); } else { while (cpio->entry_padding > 0) { - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0) return (ARCHIVE_FATAL); if (bytes_read > cpio->entry_padding) bytes_read = cpio->entry_padding; - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); cpio->entry_padding -= bytes_read; } *buff = NULL; @@ -339,9 +332,8 @@ find_newc_header(struct archive_read *a) size_t skip, bytes, skipped = 0; for (;;) { - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_newc_header)); - if (bytes < sizeof(struct cpio_newc_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), &bytes); + if (h == NULL) return (ARCHIVE_FATAL); p = h; q = p + bytes; @@ -363,7 +355,7 @@ find_newc_header(struct archive_read *a) if (memcmp("07070", p, 5) == 0 && is_hex(p, sizeof(struct cpio_newc_header))) { skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); skipped += skip; if (skipped > 0) { archive_set_error(&a->archive, @@ -386,7 +378,7 @@ find_newc_header(struct archive_read *a) } } skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); skipped += skip; } } @@ -397,7 +389,6 @@ header_newc(struct archive_read *a, struct cpio *cpio, { const void *h; const struct cpio_newc_header *header; - size_t bytes; int r; r = find_newc_header(a); @@ -405,11 +396,10 @@ header_newc(struct archive_read *a, struct cpio *cpio, return (r); /* Read fixed-size portion of header. */ - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_newc_header)); - if (bytes < sizeof(struct cpio_newc_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, sizeof(struct cpio_newc_header)); + __archive_read_consume(a, sizeof(struct cpio_newc_header)); /* Parse out hex fields. */ header = (const struct cpio_newc_header *)h; @@ -476,9 +466,8 @@ find_odc_header(struct archive_read *a) size_t skip, bytes, skipped = 0; for (;;) { - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_odc_header)); - if (bytes < sizeof(struct cpio_odc_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), &bytes); + if (h == NULL) return (ARCHIVE_FATAL); p = h; q = p + bytes; @@ -498,7 +487,7 @@ find_odc_header(struct archive_read *a) if (memcmp("070707", p, 6) == 0 && is_octal(p, sizeof(struct cpio_odc_header))) { skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); skipped += skip; if (skipped > 0) { archive_set_error(&a->archive, @@ -521,7 +510,7 @@ find_odc_header(struct archive_read *a) } } skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); skipped += skip; } } @@ -533,7 +522,6 @@ header_odc(struct archive_read *a, struct cpio *cpio, const void *h; int r; const struct cpio_odc_header *header; - size_t bytes; a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX; a->archive.archive_format_name = "POSIX octet-oriented cpio"; @@ -544,11 +532,10 @@ header_odc(struct archive_read *a, struct cpio *cpio, return (r); /* Read fixed-size portion of header. */ - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_odc_header)); - if (bytes < sizeof(struct cpio_odc_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, sizeof(struct cpio_odc_header)); + __archive_read_consume(a, sizeof(struct cpio_odc_header)); /* Parse out octal fields. */ header = (const struct cpio_odc_header *)h; @@ -582,17 +569,15 @@ header_bin_le(struct archive_read *a, struct cpio *cpio, { const void *h; const struct cpio_bin_header *header; - size_t bytes; a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE; a->archive.archive_format_name = "cpio (little-endian binary)"; /* Read fixed-size portion of header. */ - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_bin_header)); - if (bytes < sizeof(struct cpio_bin_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, sizeof(struct cpio_bin_header)); + __archive_read_consume(a, sizeof(struct cpio_bin_header)); /* Parse out binary fields. */ header = (const struct cpio_bin_header *)h; @@ -620,17 +605,15 @@ header_bin_be(struct archive_read *a, struct cpio *cpio, { const void *h; const struct cpio_bin_header *header; - size_t bytes; a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE; a->archive.archive_format_name = "cpio (big-endian binary)"; /* Read fixed-size portion of header. */ - bytes = (a->decompressor->read_ahead)(a, &h, - sizeof(struct cpio_bin_header)); - if (bytes < sizeof(struct cpio_bin_header)) + h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL); + if (h == NULL) return (ARCHIVE_FATAL); - (a->decompressor->consume)(a, sizeof(struct cpio_bin_header)); + __archive_read_consume(a, sizeof(struct cpio_bin_header)); /* Parse out binary fields. */ header = (const struct cpio_bin_header *)h; diff --git a/libarchive/archive_read_support_format_empty.c b/libarchive/archive_read_support_format_empty.c index 837fdef99..d0d18cfa4 100644 --- a/libarchive/archive_read_support_format_empty.c +++ b/libarchive/archive_read_support_format_empty.c @@ -57,11 +57,10 @@ archive_read_support_format_empty(struct archive *_a) static int archive_read_format_empty_bid(struct archive_read *a) { - int bytes_read; const void *h; - bytes_read = (a->decompressor->read_ahead)(a, &h, 1); - if (bytes_read > 0) + h = __archive_read_ahead(a, 1, NULL); + if (h != NULL) return (-1); return (1); } diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c index 481220dd4..191ab210c 100644 --- a/libarchive/archive_read_support_format_iso9660.c +++ b/libarchive/archive_read_support_format_iso9660.c @@ -288,8 +288,8 @@ archive_read_format_iso9660_bid(struct archive_read *a) * 8 sectors of the volume descriptor table. Of course, * if the I/O layer gives us more, we'll take it. */ - bytes_read = (a->decompressor->read_ahead)(a, &h, 32768 + 8*2048); - if (bytes_read < 32768 + 8*2048) + h = __archive_read_ahead(a, 32768 + 8*2048, &bytes_read); + if (h == NULL) return (-1); p = (const unsigned char *)h; @@ -334,7 +334,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a, { struct iso9660 *iso9660; struct file_info *file; - ssize_t bytes_read; int r; iso9660 = (struct iso9660 *)(a->format->data); @@ -407,20 +406,18 @@ archive_read_format_iso9660_read_header(struct archive_read *a, ssize_t step = iso9660->logical_block_size; if (step > iso9660->entry_bytes_remaining) step = iso9660->entry_bytes_remaining; - bytes_read = (a->decompressor->read_ahead)(a, &block, step); - if (bytes_read < step) { + block = __archive_read_ahead(a, step, NULL); + if (block == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Failed to read full block when scanning ISO9660 directory list"); release_file(iso9660, file); return (ARCHIVE_FATAL); } - if (bytes_read > step) - bytes_read = step; - (a->decompressor->consume)(a, bytes_read); - iso9660->current_position += bytes_read; - iso9660->entry_bytes_remaining -= bytes_read; + __archive_read_consume(a, step); + iso9660->current_position += step; + iso9660->entry_bytes_remaining -= step; for (p = (const unsigned char *)block; - *p != 0 && p < (const unsigned char *)block + bytes_read; + *p != 0 && p < (const unsigned char *)block + step; p += *p) { struct file_info *child; @@ -472,11 +469,11 @@ archive_read_format_iso9660_read_data(struct archive_read *a, return (ARCHIVE_EOF); } - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read == 0) archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Truncated input file"); - if (bytes_read <= 0) + if (buff == NULL) return (ARCHIVE_FATAL); if (bytes_read > iso9660->entry_bytes_remaining) bytes_read = iso9660->entry_bytes_remaining; @@ -485,7 +482,7 @@ archive_read_format_iso9660_read_data(struct archive_read *a, iso9660->entry_sparse_offset += bytes_read; iso9660->entry_bytes_remaining -= bytes_read; iso9660->current_position += bytes_read; - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); return (ARCHIVE_OK); } @@ -926,7 +923,7 @@ fprintf(stderr, " *** Discarding CE data.\n"); if (iso9660->current_position < offset) { off_t step = offset - iso9660->current_position; off_t bytes_read; - bytes_read = (a->decompressor->skip)(a, step); + bytes_read = __archive_read_skip(a, step); if (bytes_read < 0) return (bytes_read); iso9660->current_position = offset; @@ -940,19 +937,18 @@ fprintf(stderr, " *** Discarding CE data.\n"); if (offset == file->ce_offset) { const void *p; ssize_t size = file->ce_size; - ssize_t bytes_read; const unsigned char *rr_start; file->ce_offset = 0; file->ce_size = 0; - bytes_read = (a->decompressor->read_ahead)(a, &p, size); - if (bytes_read > size) - bytes_read = size; + p = __archive_read_ahead(a, size, NULL); + if (p == NULL) + return (ARCHIVE_FATAL); rr_start = (const unsigned char *)p; parse_rockridge(iso9660, file, rr_start, - rr_start + bytes_read); - (a->decompressor->consume)(a, bytes_read); - iso9660->current_position += bytes_read; + rr_start + size); + __archive_read_consume(a, size); + iso9660->current_position += size; add_entry(iso9660, file); } } diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index 1c0a45bdc..65ec2d699 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -187,32 +187,17 @@ cleanup(struct archive_read *a) static int mtree_bid(struct archive_read *a) { - struct mtree *mtree; - ssize_t bytes_read; - const void *h; const char *signature = "#mtree"; const char *p; - int bid; - - mtree = (struct mtree *)(a->format->data); /* Now let's look at the actual header and see if it matches. */ - bytes_read = (a->decompressor->read_ahead)(a, &h, strlen(signature)); - - if (bytes_read <= 0) - return (bytes_read); - - p = h; - bid = 0; - while (bytes_read > 0 && *signature != '\0') { - if (*p != *signature) - return (bid = 0); - bid += 8; - p++; - signature++; - bytes_read--; - } - return (bid); + p = __archive_read_ahead(a, strlen(signature), NULL); + if (p == NULL) + return (-1); + + if (strncmp(p, signature, strlen(signature)) == 0) + return (8 * strlen(signature)); + return (0); } /* @@ -1239,8 +1224,8 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi /* Accumulate line in a line buffer. */ for (;;) { /* Read some more. */ - bytes_read = (a->decompressor->read_ahead)(a, &t, 1); - if (bytes_read == 0) + t = __archive_read_ahead(a, 1, &bytes_read); + if (t == NULL) return (0); if (bytes_read < 0) return (ARCHIVE_FATAL); @@ -1263,7 +1248,7 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi return (ARCHIVE_FATAL); } memcpy(mtree->line.s + total_size, t, bytes_read); - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); total_size += bytes_read; /* Null terminate. */ mtree->line.s[total_size] = '\0'; diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index 0a649791a..b461e0b53 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/libarchive/archive_read_support_format_tar.c @@ -294,21 +294,15 @@ static int archive_read_format_tar_bid(struct archive_read *a) { int bid; - ssize_t bytes_read; const void *h; const struct archive_entry_header_ustar *header; bid = 0; /* Now let's look at the actual header and see if it matches. */ - if (a->decompressor->read_ahead != NULL) - bytes_read = (a->decompressor->read_ahead)(a, &h, 512); - else - bytes_read = 0; /* Empty file. */ - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (bytes_read < 512) - return (0); + h = __archive_read_ahead(a, 512, NULL); + if (h == NULL) + return (-1); /* If it's an end-of-archive mark, we can handle it. */ if ((*(const char *)h) == 0 @@ -479,7 +473,7 @@ archive_read_format_tar_read_data(struct archive_read *a, /* If we're at end of file, return EOF. */ if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) { - if ((a->decompressor->skip)(a, tar->entry_padding) < 0) + if (__archive_read_skip(a, tar->entry_padding) < 0) return (ARCHIVE_FATAL); tar->entry_padding = 0; *buff = NULL; @@ -488,14 +482,14 @@ archive_read_format_tar_read_data(struct archive_read *a, return (ARCHIVE_EOF); } - bytes_read = (a->decompressor->read_ahead)(a, buff, 1); - if (bytes_read == 0) { + *buff = __archive_read_ahead(a, 1, &bytes_read); + if (bytes_read < 0) + return (ARCHIVE_FATAL); + if (*buff == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Truncated tar archive"); return (ARCHIVE_FATAL); } - if (bytes_read < 0) - return (ARCHIVE_FATAL); if (bytes_read > tar->entry_bytes_remaining) bytes_read = tar->entry_bytes_remaining; /* Don't read more than is available in the @@ -507,7 +501,7 @@ archive_read_format_tar_read_data(struct archive_read *a, tar->sparse_list->remaining -= bytes_read; tar->sparse_list->offset += bytes_read; tar->entry_bytes_remaining -= bytes_read; - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); return (ARCHIVE_OK); } @@ -524,8 +518,8 @@ archive_read_format_tar_skip(struct archive_read *a) * length requested or fail, so we can rely upon the entire entry * plus padding being skipped. */ - bytes_skipped = (a->decompressor->skip)(a, tar->entry_bytes_remaining + - tar->entry_padding); + bytes_skipped = __archive_read_skip(a, + tar->entry_bytes_remaining + tar->entry_padding); if (bytes_skipped < 0) return (ARCHIVE_FATAL); @@ -552,12 +546,12 @@ tar_read_header(struct archive_read *a, struct tar *tar, const struct archive_entry_header_ustar *header; /* Read 512-byte header record */ - bytes = (a->decompressor->read_ahead)(a, &h, 512); + h = __archive_read_ahead(a, 512, &bytes); if (bytes < 0) return (bytes); if (bytes < 512) { /* Short read or EOF. */ /* Try requesting just one byte and see what happens. */ - bytes = (a->decompressor->read_ahead)(a, &h, 1); + h = __archive_read_ahead(a, 1, &bytes); if (bytes == 0) { /* * The archive ends at a 512-byte boundary but @@ -572,15 +566,15 @@ tar_read_header(struct archive_read *a, struct tar *tar, "Truncated tar archive"); return (ARCHIVE_FATAL); } - (a->decompressor->consume)(a, 512); + __archive_read_consume(a, 512); /* Check for end-of-archive mark. */ if (((*(const char *)h)==0) && archive_block_is_null((const unsigned char *)h)) { /* Try to consume a second all-null record, as well. */ - bytes = (a->decompressor->read_ahead)(a, &h, 512); - if (bytes > 0) - (a->decompressor->consume)(a, bytes); + h = __archive_read_ahead(a, 512, NULL); + if (h != NULL) + __archive_read_consume(a, 512); archive_set_error(&a->archive, 0, NULL); if (a->archive.archive_format_name == NULL) { a->archive.archive_format = ARCHIVE_FORMAT_TAR; @@ -841,10 +835,8 @@ read_body_to_string(struct archive_read *a, struct tar *tar, struct archive_string *as, const void *h) { off_t size, padded_size; - ssize_t bytes_read, bytes_to_copy; const struct archive_entry_header_ustar *header; const void *src; - char *dest; (void)tar; /* UNUSED */ header = (const struct archive_entry_header_ustar *)h; @@ -862,27 +854,14 @@ read_body_to_string(struct archive_read *a, struct tar *tar, return (ARCHIVE_FATAL); } - /* Read the body into the string. */ + /* Read the body into the string. */ padded_size = (size + 511) & ~ 511; - dest = as->s; - while (padded_size > 0) { - bytes_read = (a->decompressor->read_ahead)(a, &src, padded_size); - if (bytes_read == 0) - return (ARCHIVE_EOF); - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (bytes_read > padded_size) - bytes_read = padded_size; - (a->decompressor->consume)(a, bytes_read); - bytes_to_copy = bytes_read; - if ((off_t)bytes_to_copy > size) - bytes_to_copy = (ssize_t)size; - memcpy(dest, src, bytes_to_copy); - dest += bytes_to_copy; - size -= bytes_to_copy; - padded_size -= bytes_read; - } - *dest = '\0'; + src = __archive_read_ahead(a, padded_size, NULL); + if (src == NULL) + return (ARCHIVE_FATAL); + memcpy(as->s, src, size); + __archive_read_consume(a, padded_size); + as->s[size] = '\0'; return (ARCHIVE_OK); } @@ -1770,7 +1749,7 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar, return (ARCHIVE_OK); do { - bytes_read = (a->decompressor->read_ahead)(a, &data, 512); + data = __archive_read_ahead(a, 512, &bytes_read); if (bytes_read < 0) return (ARCHIVE_FATAL); if (bytes_read < 512) { @@ -1779,7 +1758,7 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar, "detected while reading sparse file data"); return (ARCHIVE_FATAL); } - (a->decompressor->consume)(a, 512); + __archive_read_consume(a, 512); ext = (const struct extended *)data; gnu_sparse_old_parse(tar, ext->sparse, 21); } while (ext->isextended[0] != 0); @@ -1957,7 +1936,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar) /* Skip rest of block... */ bytes_read = tar->entry_bytes_remaining - remaining; to_skip = 0x1ff & -bytes_read; - if (to_skip != (a->decompressor->skip)(a, to_skip)) + if (to_skip != __archive_read_skip(a, to_skip)) return (ARCHIVE_FATAL); return (bytes_read + to_skip); } @@ -2112,7 +2091,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start, const char *s; void *p; - bytes_read = (a->decompressor->read_ahead)(a, &t, 1); + t = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0) return (ARCHIVE_FATAL); s = t; /* Start of line? */ @@ -2126,7 +2105,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start, "Line too long"); return (ARCHIVE_FATAL); } - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); *start = s; return (bytes_read); } @@ -2144,7 +2123,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start, return (ARCHIVE_FATAL); } memcpy(tar->line.s + total_size, t, bytes_read); - (a->decompressor->consume)(a, bytes_read); + __archive_read_consume(a, bytes_read); total_size += bytes_read; /* If we found '\n', clean up and return. */ if (p != NULL) { @@ -2152,7 +2131,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start, return (total_size); } /* Read some more. */ - bytes_read = (a->decompressor->read_ahead)(a, &t, 1); + t = __archive_read_ahead(a, 1, &bytes_read); if (bytes_read <= 0) return (ARCHIVE_FATAL); s = t; /* Start of line? */ diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index a7703502b..a22eaa0a3 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/libarchive/archive_read_support_format_zip.c @@ -169,7 +169,7 @@ archive_read_format_zip_bid(struct archive_read *a) const void *buff; size_t bytes_avail, offset; - if ((p = __archive_read_ahead(a, 4)) == NULL) + if ((p = __archive_read_ahead(a, 4, NULL)) == NULL) return (-1); /* @@ -203,8 +203,8 @@ archive_read_format_zip_bid(struct archive_read *a) offset = 0; while (offset < 124000) { /* Get 4k of data beyond where we stopped. */ - bytes_avail = (a->decompressor->read_ahead)(a, &buff, - offset + 4096); + buff = __archive_read_ahead(a, offset + 4096, + &bytes_avail); if (bytes_avail < offset + 1) break; p = (const char *)buff + offset; @@ -246,7 +246,7 @@ skip_sfx(struct archive_read *a) * reduce the chance of a false positive. */ for (;;) { - bytes = (a->decompressor->read_ahead)(a, &h, 4); + h = __archive_read_ahead(a, 4, &bytes); if (bytes < 4) return (ARCHIVE_FATAL); p = h; @@ -262,7 +262,7 @@ skip_sfx(struct archive_read *a) /* TODO: Additional verification here. */ if (memcmp("PK\003\004", p, 4) == 0) { skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); return (ARCHIVE_OK); } p += 4; @@ -274,7 +274,7 @@ skip_sfx(struct archive_read *a) } } skip = p - (const char *)h; - (a->decompressor->consume)(a, skip); + __archive_read_consume(a, skip); } } @@ -298,7 +298,7 @@ archive_read_format_zip_read_header(struct archive_read *a, zip->entry_uncompressed_bytes_read = 0; zip->entry_compressed_bytes_read = 0; zip->entry_crc32 = crc32(0, NULL, 0); - if ((h = __archive_read_ahead(a, 4)) == NULL) + if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) return (ARCHIVE_FATAL); signature = (const char *)h; @@ -307,7 +307,7 @@ archive_read_format_zip_read_header(struct archive_read *a, r = skip_sfx(a); if (r < ARCHIVE_WARN) return (r); - if ((h = __archive_read_ahead(a, 4)) == NULL) + if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) return (ARCHIVE_FATAL); signature = (const char *)h; } @@ -324,8 +324,8 @@ archive_read_format_zip_read_header(struct archive_read *a, * skip the PK00; the first real file header should follow. */ if (signature[2] == '0' && signature[3] == '0') { - (a->decompressor->consume)(a, 4); - if ((h = __archive_read_ahead(a, 4)) == NULL) + __archive_read_consume(a, 4); + if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) return (ARCHIVE_FATAL); signature = (const char *)h; if (signature[0] != 'P' || signature[1] != 'K') { @@ -376,7 +376,7 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, const struct zip_file_header *p; const void *h; - if ((p = __archive_read_ahead(a, sizeof *p)) == NULL) { + if ((p = __archive_read_ahead(a, sizeof *p, NULL)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file header"); return (ARCHIVE_FATAL); @@ -403,11 +403,11 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, zip->uncompressed_size = archive_le32dec(p->uncompressed_size); zip->compressed_size = archive_le32dec(p->compressed_size); - (a->decompressor->consume)(a, sizeof(struct zip_file_header)); + __archive_read_consume(a, sizeof(struct zip_file_header)); /* Read the filename. */ - if ((h = __archive_read_ahead(a, zip->filename_length)) == NULL) { + if ((h = __archive_read_ahead(a, zip->filename_length, NULL)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file header"); return (ARCHIVE_FATAL); @@ -415,7 +415,7 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL) __archive_errx(1, "Out of memory"); archive_strncpy(&zip->pathname, h, zip->filename_length); - (a->decompressor->consume)(a, zip->filename_length); + __archive_read_consume(a, zip->filename_length); archive_entry_set_pathname(entry, zip->pathname.s); if (zip->pathname.s[archive_strlen(&zip->pathname) - 1] == '/') @@ -424,13 +424,13 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry, zip->mode = AE_IFREG | 0777; /* Read the extra data. */ - if ((h = __archive_read_ahead(a, zip->extra_length)) == NULL) { + if ((h = __archive_read_ahead(a, zip->extra_length, NULL)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file header"); return (ARCHIVE_FATAL); } process_extra(h, zip); - (a->decompressor->consume)(a, zip->extra_length); + __archive_read_consume(a, zip->extra_length); /* Populate some additional entry fields: */ archive_entry_set_mode(entry, zip->mode); @@ -499,7 +499,7 @@ archive_read_format_zip_read_data(struct archive_read *a, if (zip->flags & ZIP_LENGTH_AT_END) { const char *p; - if ((p = __archive_read_ahead(a, 16)) == NULL) { + if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP end-of-file record"); @@ -508,7 +508,7 @@ archive_read_format_zip_read_data(struct archive_read *a, zip->crc32 = archive_le32dec(p + 4); zip->compressed_size = archive_le32dec(p + 8); zip->uncompressed_size = archive_le32dec(p + 12); - (a->decompressor->consume)(a, 16); + __archive_read_consume(a, 16); } /* Check file size, CRC against these values. */ @@ -617,7 +617,7 @@ zip_read_data_none(struct archive_read *a, const void **buff, * available bytes; asking for more than that forces the * decompressor to combine reads by copying data. */ - bytes_avail = (a->decompressor->read_ahead)(a, buff, 1); + *buff = __archive_read_ahead(a, 1, &bytes_avail); if (bytes_avail <= 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file data"); @@ -625,7 +625,7 @@ zip_read_data_none(struct archive_read *a, const void **buff, } if (bytes_avail > zip->entry_bytes_remaining) bytes_avail = zip->entry_bytes_remaining; - (a->decompressor->consume)(a, bytes_avail); + __archive_read_consume(a, bytes_avail); *size = bytes_avail; *offset = zip->entry_offset; zip->entry_offset += *size; @@ -683,7 +683,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff, * available bytes; asking for more than that forces the * decompressor to combine reads by copying data. */ - bytes_avail = (a->decompressor->read_ahead)(a, &compressed_buff, 1); + compressed_buff = __archive_read_ahead(a, 1, &bytes_avail); if (bytes_avail <= 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file body"); @@ -722,7 +722,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff, /* Consume as much as the compressor actually used. */ bytes_avail = zip->stream.total_in; - (a->decompressor->consume)(a, bytes_avail); + __archive_read_consume(a, bytes_avail); zip->entry_bytes_remaining -= bytes_avail; zip->entry_compressed_bytes_read += bytes_avail; @@ -779,7 +779,7 @@ archive_read_format_zip_read_data_skip(struct archive_read *a) * If the length is at the beginning, we can skip the * compressed data much more quickly. */ - bytes_skipped = (a->decompressor->skip)(a, zip->entry_bytes_remaining); + bytes_skipped = __archive_read_skip(a, zip->entry_bytes_remaining); if (bytes_skipped < 0) return (ARCHIVE_FATAL);