Various style and portability fixes, including:
* Enforce option interface can only be used before the archive is opened * Correctly handle large skips on platforms with 32-bit off_t * Use int64_t instead of off_t
This commit is contained in:
parent
081e9a983c
commit
e2196d3e85
@ -121,6 +121,9 @@ archive_read_set_format_options(struct archive *_a, const char *s)
|
||||
size_t i;
|
||||
int len, r;
|
||||
|
||||
__archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_format_options");
|
||||
|
||||
if (s == NULL || *s == '\0')
|
||||
return (ARCHIVE_OK);
|
||||
a = (struct archive_read *)_a;
|
||||
@ -165,12 +168,14 @@ archive_read_set_filter_options(struct archive *_a, const char *s)
|
||||
char key[64], val[64];
|
||||
int len, r;
|
||||
|
||||
__archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_filter_options");
|
||||
|
||||
if (s == NULL || *s == '\0')
|
||||
return (ARCHIVE_OK);
|
||||
a = (struct archive_read *)_a;
|
||||
__archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_set_filter_options");
|
||||
filter = a->filter;
|
||||
len = 0;
|
||||
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
|
||||
bidder = filter->bidder;
|
||||
@ -206,6 +211,10 @@ archive_read_set_options(struct archive *_a, const char *s)
|
||||
{
|
||||
int r;
|
||||
|
||||
__archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_options");
|
||||
archive_clear_error(_a);
|
||||
|
||||
r = archive_read_set_format_options(_a, s);
|
||||
if (r != ARCHIVE_OK)
|
||||
return (r);
|
||||
@ -242,13 +251,26 @@ client_read_proxy(struct archive_read_filter *self, const void **buff)
|
||||
static int64_t
|
||||
client_skip_proxy(struct archive_read_filter *self, int64_t request)
|
||||
{
|
||||
int64_t r;
|
||||
int64_t ask, get, total;
|
||||
/* Limit our maximum seek request to 1GB on platforms
|
||||
* with 32-bit off_t (such as Windows). */
|
||||
int64_t skip_limit = ((int64_t)1) << (sizeof(off_t) * 8 - 2);
|
||||
|
||||
if (self->archive->client.skipper == NULL)
|
||||
return (0);
|
||||
r = (self->archive->client.skipper)(&self->archive->archive,
|
||||
self->data, request);
|
||||
self->archive->archive.raw_position += r;
|
||||
return (r);
|
||||
total = 0;
|
||||
for (;;) {
|
||||
ask = request;
|
||||
if (ask > skip_limit)
|
||||
ask = skip_limit;
|
||||
get = (self->archive->client.skipper)(&self->archive->archive,
|
||||
self->data, ask);
|
||||
if (get == 0)
|
||||
return (total);
|
||||
request -= get;
|
||||
self->archive->archive.raw_position += get;
|
||||
total += get;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -277,6 +299,7 @@ archive_read_open2(struct archive *_a, void *client_data,
|
||||
|
||||
__archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_open");
|
||||
archive_clear_error(&a->archive);
|
||||
|
||||
if (client_reader == NULL)
|
||||
__archive_errx(1,
|
||||
@ -736,7 +759,7 @@ _archive_read_close(struct archive *_a)
|
||||
/*
|
||||
* Release memory and other resources.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
_archive_read_finish(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
@ -1121,6 +1144,8 @@ __archive_read_skip(struct archive_read *a, int64_t request)
|
||||
if (skipped == request)
|
||||
return (skipped);
|
||||
/* We hit EOF before we satisfied the skip request. */
|
||||
if (skipped < 0) // Map error code to 0 for error message below.
|
||||
skipped = 0;
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Truncated input file (needed %jd bytes, only %jd available)",
|
||||
@ -1140,7 +1165,7 @@ __archive_read_skip_lenient(struct archive_read *a, int64_t request)
|
||||
int64_t
|
||||
__archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
|
||||
{
|
||||
off_t bytes_skipped, total_bytes_skipped = 0;
|
||||
int64_t bytes_skipped, total_bytes_skipped = 0;
|
||||
size_t min;
|
||||
|
||||
if (filter->fatal)
|
||||
@ -1155,7 +1180,7 @@ __archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
|
||||
total_bytes_skipped += bytes_skipped;
|
||||
}
|
||||
if (filter->client_avail > 0) {
|
||||
min = minimum(request, (off_t)filter->client_avail);
|
||||
min = minimum(request, (int64_t)filter->client_avail);
|
||||
bytes_skipped = __archive_read_filter_consume(filter, min);
|
||||
request -= bytes_skipped;
|
||||
total_bytes_skipped += bytes_skipped;
|
||||
@ -1189,10 +1214,8 @@ __archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
|
||||
* have to use ordinary reads to finish out the request.
|
||||
*/
|
||||
while (request > 0) {
|
||||
const void* dummy_buffer;
|
||||
ssize_t bytes_read;
|
||||
dummy_buffer = __archive_read_filter_ahead(filter,
|
||||
1, &bytes_read);
|
||||
(void)__archive_read_filter_ahead(filter, 1, &bytes_read);
|
||||
if (bytes_read < 0)
|
||||
return (bytes_read);
|
||||
if (bytes_read == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user