Move ZIP_CODEC defines to zipint.h (not public). Add zip_source_seek_compute_offset to simplify ZIP_SOURCE_SEEK implementations.
diff --git a/TODO b/TODO index 9a1cecb..606543c 100644 --- a/TODO +++ b/TODO
@@ -75,6 +75,9 @@ Cleanup ======= +* use bool +* use ZIP_SOURCE_SUPPORTS_{READABLE,SEEKABLE,WRITABLE} +* use zip_source_seek_compute_offset * move compat refs from zipint.h to own file, and include that in zipint.h and src * get rid of zip_get_{compression,encryption}_implementation * use zip_*int*_t internally @@ -275,6 +278,7 @@ ** int zip_source_commit_write(zip_source_t *); ** void zip_source_rollback_write(zip_source_t *); ** zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t); +** 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); - document deprecations ** int zip_error_get_sys_type(int); /* use zip_error_system_type */ ** void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
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; };
diff --git a/regress/source_hole.c b/regress/source_hole.c index 29cf888..95d7fa7 100644 --- a/regress/source_hole.c +++ b/regress/source_hole.c
@@ -268,39 +268,13 @@ static zip_int64_t buffer_seek(buffer_t *buffer, void *data, zip_uint64_t length, zip_error_t *error) { - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, length, error); - zip_int64_t offset; - - if (args == NULL) { + zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, length, error); + + if (new_offset < 0) { return -1; } - /* TODO: check for overflow */ - 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 = args->offset; - break; - - default: - offset = -1; - break; - } - - if (offset < 0 || offset > (zip_int64_t)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; }