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;
}