Move ZIP_CODEC defines to zipint.h (not public). Add zip_source_seek_compute_offset to simplify ZIP_SOURCE_SEEK implementations.
diff --git a/lib/zip.h b/lib/zip.h index 5539930..aa9b683 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -100,11 +100,6 @@ #define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX #define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX -/* flags for compression and encryption sources */ - -#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ -#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ - /* libzip error codes */ @@ -396,6 +391,7 @@ ZIP_EXTERN int zip_source_open(zip_source_t *); ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t); ZIP_EXTERN void zip_source_rollback_write(zip_source_t *); +ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *); ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *); ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t); ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
diff --git a/lib/zip_set_file_compression.c b/lib/zip_set_file_compression.c index 1e45f24..7bb0bf9 100644 --- a/lib/zip_set_file_compression.c +++ b/lib/zip_set_file_compression.c
@@ -36,8 +36,7 @@ ZIP_EXTERN int -zip_set_file_compression(zip_t *za, zip_uint64_t idx, - zip_int32_t method, zip_uint32_t flags) +zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags) { zip_entry_t *e; zip_int32_t old_method;
diff --git a/lib/zip_source_buffer.c b/lib/zip_source_buffer.c index 3914733..4ecec6b 100644 --- a/lib/zip_source_buffer.c +++ b/lib/zip_source_buffer.c
@@ -361,36 +361,13 @@ static int buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) { - zip_int64_t offset; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, error); - - if (args == NULL) - return -1; - - switch (args->whence) { - case SEEK_CUR: - offset = (zip_int64_t)buffer->offset + args->offset; - break; - - case SEEK_END: - offset = (zip_int64_t)buffer->size + args->offset; - break; - - case SEEK_SET: - offset = (zip_int64_t)args->offset; - break; - - default: - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; + zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error); + + if (new_offset < 0) { + return -1; } - - if (offset < 0 || (zip_uint64_t)offset > buffer->size) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return -1; - } - - buffer->offset = (zip_uint64_t)offset; + + buffer->offset = (zip_uint64_t)new_offset; return 0; }
diff --git a/lib/zip_source_seek.c b/lib/zip_source_seek.c index 24fc05c..6779ad7 100644 --- a/lib/zip_source_seek.c +++ b/lib/zip_source_seek.c
@@ -53,3 +53,40 @@ return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0); } + + +zip_int64_t +zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error) +{ + zip_int64_t new_offset; + zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error); + + if (args == NULL) { + return -1; + } + + switch (args->whence) { + case SEEK_CUR: + new_offset = (zip_int64_t)offset + args->offset; + break; + + case SEEK_END: + new_offset = (zip_int64_t)length + args->offset; + break; + + case SEEK_SET: + new_offset = args->offset; + break; + + default: + zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; + } + + if (new_offset < 0 || (zip_uint64_t)new_offset > length) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; + } + + return new_offset; +}
diff --git a/lib/zip_source_window.c b/lib/zip_source_window.c index 69a0c91..f02d048 100644 --- a/lib/zip_source_window.c +++ b/lib/zip_source_window.c
@@ -180,36 +180,13 @@ case ZIP_SOURCE_SEEK: { - zip_int64_t new_offset; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); - if (args == NULL) - return -1; - - switch (args->whence) { - case SEEK_CUR: - new_offset = (zip_int64_t)ctx->offset + args->offset; - break; - - case SEEK_END: - new_offset = (zip_int64_t)ctx->end + args->offset; - break; - - case SEEK_SET: - new_offset = (zip_int64_t)ctx->start + args->offset; - break; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (new_offset < (zip_int64_t)ctx->start || (zip_uint64_t)new_offset > ctx->end) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + if (new_offset < 0) { return -1; } - ctx->offset = (zip_uint64_t)new_offset; + ctx->offset = (zip_uint64_t)new_offset + ctx->start; return 0; }
diff --git a/lib/zipint.h b/lib/zipint.h index bab9d43..9111949 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -180,6 +180,12 @@ /* This section contains API that won't materialize like this. It's placed in the internal section, pending cleanup. */ +/* flags for compression and encryption sources */ + +#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ +#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ + + typedef zip_source_t *(*zip_compression_implementation)(zip_t *, zip_source_t *, zip_int32_t, int); typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *, zip_uint16_t, int, const char *); @@ -273,7 +279,7 @@ zip_string_t *comment_orig; /* archive comment */ zip_string_t *comment_changes; /* changed archive comment */ - int comment_changed; /* whether archive comment was changed */ + bool comment_changed; /* whether archive comment was changed */ zip_uint64_t nentry; /* number of entries */ zip_uint64_t nentry_alloc; /* number of entries allocated */ @@ -291,7 +297,7 @@ struct zip_file { zip_t *za; /* zip archive containing this file */ zip_error_t error; /* error information */ - int eof; + bool eof; zip_source_t *src; /* data source */ }; @@ -307,8 +313,8 @@ struct zip_dirent { zip_uint32_t changed; - int local_extra_fields_read; /* whether we already read in local header extra fields */ - int cloned; /* whether this instance is cloned, and thus shares non-changed strings */ + bool local_extra_fields_read; /* whether we already read in local header extra fields */ + bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */ zip_uint16_t version_madeby; /* (c) version of creator */ zip_uint16_t version_needed; /* (cl) version needed to extract */ @@ -381,7 +387,7 @@ zip_dirent_t *orig; zip_dirent_t *changes; zip_source_t *source; - int deleted; + bool deleted; };