diff options
112 files changed, 585 insertions, 266 deletions
diff --git a/src/Common/libzip/compat.h b/src/Common/libzip/compat.h index f2e4c6c5..e0a27beb 100644 --- a/src/Common/libzip/compat.h +++ b/src/Common/libzip/compat.h @@ -3,7 +3,7 @@ /* compat.h -- compatibility defines. - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -81,6 +81,11 @@ typedef char bool; #define EOVERFLOW EFBIG #endif +/* not supported on at least Windows */ +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + #ifdef _WIN32 #if defined(HAVE__CHMOD) #define chmod _chmod @@ -120,9 +125,6 @@ typedef char bool; #if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64) #define strtoull _strtoui64 #endif -#if defined(HAVE__UMASK) -#define umask _umask -#endif #if defined(HAVE__UNLINK) #define unlink _unlink #endif @@ -136,11 +138,6 @@ typedef char bool; #define ftello(s) ((long)ftell((s))) #endif -#ifndef HAVE_MKSTEMP -int _zip_mkstemp(char *); -#define mkstemp _zip_mkstemp -#endif - #if !defined(HAVE_STRCASECMP) #if defined(HAVE__STRICMP) #define strcasecmp _stricmp @@ -203,4 +200,8 @@ int _zip_mkstemp(char *); #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) #endif +#ifndef S_ISREG +#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) +#endif + #endif /* compat.h */ diff --git a/src/Common/libzip/zip.h b/src/Common/libzip/zip.h index b7cd60c5..34b544ef 100644 --- a/src/Common/libzip/zip.h +++ b/src/Common/libzip/zip.h @@ -3,7 +3,7 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -134,6 +134,7 @@ extern "C" { #define ZIP_ER_INUSE 29 /* N Resource still in use */ #define ZIP_ER_TELL 30 /* S Tell error */ #define ZIP_ER_COMPRESSED_DATA 31 /* N Compressed data invalid */ +#define ZIP_ER_CANCELLED 32 /* N Operation cancelled */ /* type of system error value */ @@ -162,6 +163,7 @@ extern "C" { /* 15-17 - Reserved by PKWARE */ #define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ #define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ +#define ZIP_CM_LZMA2 33 #define ZIP_CM_XZ 95 /* XZ compressed data */ #define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ #define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ @@ -229,7 +231,8 @@ enum zip_source_cmd { ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ ZIP_SOURCE_REMOVE, /* remove file */ ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */ - ZIP_SOURCE_BEGIN_WRITE_CLONING /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */ + ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */ + ZIP_SOURCE_ACCEPT_EMPTY /* whether empty files are valid archives */ }; typedef enum zip_source_cmd zip_source_cmd_t; @@ -321,6 +324,7 @@ typedef zip_uint32_t zip_flags_t; typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t); typedef void (*zip_progress_callback)(zip_t *, double, void *); +typedef int (*zip_cancel_callback)(zip_t *, void *); #ifndef ZIP_DISABLE_DEPRECATED typedef void (*zip_progress_callback_t)(double); @@ -373,6 +377,7 @@ ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t); ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t); ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_set_dostime(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); ZIP_EXTERN int zip_file_set_encryption(zip_t *, zip_uint64_t, zip_uint16_t, const char *); ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t); ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t); @@ -393,6 +398,7 @@ ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t); ZIP_EXTERN zip_t * zip_open(const char *, int, int *); ZIP_EXTERN zip_t * zip_open_from_source(zip_source_t *, int, zip_error_t *); ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *, double, zip_progress_callback, void (*)(void *), void *); +ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *, zip_cancel_callback, void (*)(void *), void *); ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t); ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int); ZIP_EXTERN int zip_set_default_password(zip_t *, const char *); diff --git a/src/Common/libzip/zip_add.c b/src/Common/libzip/zip_add.c index f09c9ffe..19542357 100644 --- a/src/Common/libzip/zip_add.c +++ b/src/Common/libzip/zip_add.c @@ -1,6 +1,6 @@ /* zip_add.c -- add file via callback function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_add_dir.c b/src/Common/libzip/zip_add_dir.c index 6beb929b..88fcf53a 100644 --- a/src/Common/libzip/zip_add_dir.c +++ b/src/Common/libzip/zip_add_dir.c @@ -1,6 +1,6 @@ /* zip_add_dir.c -- add directory - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_add_entry.c b/src/Common/libzip/zip_add_entry.c index 45def7a1..f52e0b5c 100644 --- a/src/Common/libzip/zip_add_entry.c +++ b/src/Common/libzip/zip_add_entry.c @@ -1,6 +1,6 @@ /* zip_add_entry.c -- create and init struct zip_entry - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_algorithm_deflate.c b/src/Common/libzip/zip_algorithm_deflate.c index ba5ad439..30e072a5 100644 --- a/src/Common/libzip/zip_algorithm_deflate.c +++ b/src/Common/libzip/zip_algorithm_deflate.c @@ -1,6 +1,6 @@ /* zip_algorithm_deflate.c -- deflate (de)compression routines - Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -51,6 +51,7 @@ allocate(bool compress, int compression_flags, zip_error_t *error) { struct ctx *ctx; if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { + zip_error_set(error, ZIP_ET_SYS, errno); return NULL; } diff --git a/src/Common/libzip/zip_buffer.c b/src/Common/libzip/zip_buffer.c index 37977f09..8c24b27e 100644 --- a/src/Common/libzip/zip_buffer.c +++ b/src/Common/libzip/zip_buffer.c @@ -1,6 +1,6 @@ /* zip_buffer.c -- bounds checked access to memory buffer - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c index 26572261..2a9fed25 100644 --- a/src/Common/libzip/zip_close.c +++ b/src/Common/libzip/zip_close.c @@ -1,6 +1,6 @@ /* zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -73,8 +73,10 @@ zip_close(zip_t *za) { if (survivors == 0) { if ((za->open_flags & ZIP_TRUNCATE) || changed) { if (zip_source_remove(za->src) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) { + _zip_error_set_from_source(&za->error, za->src); + return -1; + } } } zip_discard(za); @@ -158,14 +160,23 @@ zip_close(zip_t *za) { } } - _zip_progress_start(za->progress); + if (_zip_progress_start(za->progress) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + zip_source_rollback_write(za->src); + free(filelist); + return -1; + } error = 0; for (j = 0; j < survivors; j++) { int new_data; zip_entry_t *entry; zip_dirent_t *de; - _zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors); + if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + error = 1; + break; + } i = filelist[j].idx; entry = za->entry + i; @@ -256,10 +267,9 @@ zip_close(zip_t *za) { _zip_error_set_from_source(&za->error, za->src); error = 1; } + _zip_progress_end(za->progress); } - _zip_progress_end(za->progress); - if (error) { zip_source_rollback_write(za->src); return -1; @@ -543,7 +553,10 @@ copy_data(zip_t *za, zip_uint64_t len) { len -= n; - _zip_progress_update(za->progress, (total - (double)len) / total); + if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + return -1; + } } byte_array_fini(buf); @@ -576,7 +589,11 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { } if (n == BUFSIZE && za->progress && data_length > 0) { current += n; - _zip_progress_update(za->progress, (double)current / (double)data_length); + if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + ret = -1; + break; + } } } diff --git a/src/Common/libzip/zip_delete.c b/src/Common/libzip/zip_delete.c index 458a1b84..97701a01 100644 --- a/src/Common/libzip/zip_delete.c +++ b/src/Common/libzip/zip_delete.c @@ -1,6 +1,6 @@ /* zip_delete.c -- delete file from zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_dir_add.c b/src/Common/libzip/zip_dir_add.c index 46c76cf7..c40b1cb9 100644 --- a/src/Common/libzip/zip_dir_add.c +++ b/src/Common/libzip/zip_dir_add.c @@ -1,6 +1,6 @@ /* zip_dir_add.c -- add directory - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_dirent.c b/src/Common/libzip/zip_dirent.c index 4dcb3391..2bbb63dc 100644 --- a/src/Common/libzip/zip_dirent.c +++ b/src/Common/libzip/zip_dirent.c @@ -1,6 +1,6 @@ /* zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -41,7 +41,6 @@ #include "zipint.h" -static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str); static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *); static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error); @@ -978,7 +977,7 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { } -static time_t +time_t _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { struct tm tm; @@ -1066,21 +1065,26 @@ _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *err void _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { - struct tm *tm; + struct tm *tpm; - tm = localtime(&intime); - if (tm == NULL) { +#ifdef HAVE_LOCALTIME_R + struct tm tm; + tpm = localtime_r(&intime, &tm); +#else + tpm = localtime(&intime); +#endif + if (tpm == NULL) { /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */ *ddate = (1 << 5) + 1; *dtime = 0; return; } - if (tm->tm_year < 80) { - tm->tm_year = 80; + if (tpm->tm_year < 80) { + tpm->tm_year = 80; } - *ddate = (zip_uint16_t)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); - *dtime = (zip_uint16_t)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); + *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday); + *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1)); return; } diff --git a/src/Common/libzip/zip_discard.c b/src/Common/libzip/zip_discard.c index 94972cfb..12f06367 100644 --- a/src/Common/libzip/zip_discard.c +++ b/src/Common/libzip/zip_discard.c @@ -1,6 +1,6 @@ /* zip_discard.c -- discard and free struct zip - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_entry.c b/src/Common/libzip/zip_entry.c index 55f64581..52ecaef9 100644 --- a/src/Common/libzip/zip_entry.c +++ b/src/Common/libzip/zip_entry.c @@ -1,6 +1,6 @@ /* zip_entry.c -- struct zip_entry helper functions - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_err_str.c b/src/Common/libzip/zip_err_str.c index 3d9ee54e..e0a04a94 100644 --- a/src/Common/libzip/zip_err_str.c +++ b/src/Common/libzip/zip_err_str.c @@ -5,16 +5,80 @@ #include "zipint.h" -const char *const _zip_err_str[] = { - "No error", "Multi-disk zip archives not supported", "Renaming temporary file failed", "Closing zip archive failed", "Seek error", "Read error", "Write error", "CRC error", "Containing zip archive was closed", "No such file", "File already exists", "Can't open file", "Failure to create temporary file", "Zlib error", "Malloc failure", "Entry has been changed", "Compression method not supported", "Premature end of file", "Invalid argument", "Not a zip archive", "Internal error", "Zip archive inconsistent", "Can't remove file", "Entry has been deleted", "Encryption method not supported", "Read-only archive", "No password provided", "Wrong password provided", "Operation not supported", "Resource still in use", "Tell error", "Compressed data invalid", +const char * const _zip_err_str[] = { + "No error", + "Multi-disk zip archives not supported", + "Renaming temporary file failed", + "Closing zip archive failed", + "Seek error", + "Read error", + "Write error", + "CRC error", + "Containing zip archive was closed", + "No such file", + "File already exists", + "Can't open file", + "Failure to create temporary file", + "Zlib error", + "Malloc failure", + "Entry has been changed", + "Compression method not supported", + "Premature end of file", + "Invalid argument", + "Not a zip archive", + "Internal error", + "Zip archive inconsistent", + "Can't remove file", + "Entry has been deleted", + "Encryption method not supported", + "Read-only archive", + "No password provided", + "Wrong password provided", + "Operation not supported", + "Resource still in use", + "Tell error", + "Compressed data invalid", + "Operation cancelled", }; -const int _zip_nerr_str = sizeof(_zip_err_str) / sizeof(_zip_err_str[0]); +const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); #define N ZIP_ET_NONE #define S ZIP_ET_SYS #define Z ZIP_ET_ZLIB const int _zip_err_type[] = { - N, N, S, S, S, S, S, N, N, N, N, S, S, Z, N, N, N, N, N, N, N, N, S, N, N, N, N, N, N, N, S, N, + N, + N, + S, + S, + S, + S, + S, + N, + N, + N, + N, + S, + S, + Z, + N, + N, + N, + N, + N, + N, + N, + N, + S, + N, + N, + N, + N, + N, + N, + N, + S, + N, + N, }; diff --git a/src/Common/libzip/zip_error.c b/src/Common/libzip/zip_error.c index e05ae500..a0f74f02 100644 --- a/src/Common/libzip/zip_error.c +++ b/src/Common/libzip/zip_error.c @@ -1,6 +1,6 @@ /* zip_error.c -- zip_error_t helper functions - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_error_clear.c b/src/Common/libzip/zip_error_clear.c index 6b3a8da0..eec1568f 100644 --- a/src/Common/libzip/zip_error_clear.c +++ b/src/Common/libzip/zip_error_clear.c @@ -1,6 +1,6 @@ /* zip_error_clear.c -- clear zip error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_error_get.c b/src/Common/libzip/zip_error_get.c index 12341d1c..9588b4c4 100644 --- a/src/Common/libzip/zip_error_get.c +++ b/src/Common/libzip/zip_error_get.c @@ -1,6 +1,6 @@ /* zip_error_get.c -- get zip error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_error_get_sys_type.c b/src/Common/libzip/zip_error_get_sys_type.c index 80bfc0ca..3dfe5c26 100644 --- a/src/Common/libzip/zip_error_get_sys_type.c +++ b/src/Common/libzip/zip_error_get_sys_type.c @@ -1,6 +1,6 @@ /* zip_error_get_sys_type.c -- return type of system error code - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_error_strerror.c b/src/Common/libzip/zip_error_strerror.c index 0f650b5f..63585779 100644 --- a/src/Common/libzip/zip_error_strerror.c +++ b/src/Common/libzip/zip_error_strerror.c @@ -1,6 +1,6 @@ /* zip_error_sterror.c -- get string representation of struct zip_error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_error_to_str.c b/src/Common/libzip/zip_error_to_str.c index bf515698..13faf962 100644 --- a/src/Common/libzip/zip_error_to_str.c +++ b/src/Common/libzip/zip_error_to_str.c @@ -1,6 +1,6 @@ /* zip_error_to_str.c -- get string representation of zip error code - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_extra_field.c b/src/Common/libzip/zip_extra_field.c index a17e4916..7114a251 100644 --- a/src/Common/libzip/zip_extra_field.c +++ b/src/Common/libzip/zip_extra_field.c @@ -1,6 +1,6 @@ /* zip_extra_field.c -- manipulate extra fields - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_extra_field_api.c b/src/Common/libzip/zip_extra_field_api.c index 31808ded..605f95d0 100644 --- a/src/Common/libzip/zip_extra_field_api.c +++ b/src/Common/libzip/zip_extra_field_api.c @@ -1,6 +1,6 @@ /* zip_extra_field_api.c -- public extra fields API functions - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fclose.c b/src/Common/libzip/zip_fclose.c index 1c69a966..6eb9dc91 100644 --- a/src/Common/libzip/zip_fclose.c +++ b/src/Common/libzip/zip_fclose.c @@ -1,6 +1,6 @@ /* zip_fclose.c -- close file in zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fdopen.c b/src/Common/libzip/zip_fdopen.c index 32709355..5a732cd4 100644 --- a/src/Common/libzip/zip_fdopen.c +++ b/src/Common/libzip/zip_fdopen.c @@ -1,6 +1,6 @@ /* zip_fdopen.c -- open read-only archive from file descriptor - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_add.c b/src/Common/libzip/zip_file_add.c index c2c13d66..c019d8dd 100644 --- a/src/Common/libzip/zip_file_add.c +++ b/src/Common/libzip/zip_file_add.c @@ -1,6 +1,6 @@ /* zip_file_add.c -- add file via callback function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_error_clear.c b/src/Common/libzip/zip_file_error_clear.c index 2e7dcea8..47e5da63 100644 --- a/src/Common/libzip/zip_file_error_clear.c +++ b/src/Common/libzip/zip_file_error_clear.c @@ -1,6 +1,6 @@ /* zip_file_error_clear.c -- clear zip file error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_error_get.c b/src/Common/libzip/zip_file_error_get.c index 1d13807f..1ed68df1 100644 --- a/src/Common/libzip/zip_file_error_get.c +++ b/src/Common/libzip/zip_file_error_get.c @@ -1,6 +1,6 @@ /* zip_file_error_get.c -- get zip file error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_get_comment.c b/src/Common/libzip/zip_file_get_comment.c index ad944aaf..8f68141a 100644 --- a/src/Common/libzip/zip_file_get_comment.c +++ b/src/Common/libzip/zip_file_get_comment.c @@ -1,6 +1,6 @@ /* zip_file_get_comment.c -- get file comment - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_get_external_attributes.c b/src/Common/libzip/zip_file_get_external_attributes.c index e2e55357..ebc20580 100644 --- a/src/Common/libzip/zip_file_get_external_attributes.c +++ b/src/Common/libzip/zip_file_get_external_attributes.c @@ -1,6 +1,6 @@ /* zip_file_get_external_attributes.c -- get opsys/external attributes - Copyright (C) 2013-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_get_offset.c b/src/Common/libzip/zip_file_get_offset.c index 858a78a4..9ea89090 100644 --- a/src/Common/libzip/zip_file_get_offset.c +++ b/src/Common/libzip/zip_file_get_offset.c @@ -1,6 +1,6 @@ /* zip_file_get_offset.c -- get offset of file data in archive. - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_rename.c b/src/Common/libzip/zip_file_rename.c index cc42dfcc..7ca428c4 100644 --- a/src/Common/libzip/zip_file_rename.c +++ b/src/Common/libzip/zip_file_rename.c @@ -1,6 +1,6 @@ /* zip_file_rename.c -- rename file in zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_replace.c b/src/Common/libzip/zip_file_replace.c index 70b379aa..87401f4a 100644 --- a/src/Common/libzip/zip_file_replace.c +++ b/src/Common/libzip/zip_file_replace.c @@ -1,6 +1,6 @@ /* zip_file_replace.c -- replace file via callback function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_set_comment.c b/src/Common/libzip/zip_file_set_comment.c index ae6b6021..c309db8b 100644 --- a/src/Common/libzip/zip_file_set_comment.c +++ b/src/Common/libzip/zip_file_set_comment.c @@ -1,6 +1,6 @@ /* zip_file_set_comment.c -- set comment for file in archive - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_set_external_attributes.c b/src/Common/libzip/zip_file_set_external_attributes.c index c412f272..bb2ea614 100644 --- a/src/Common/libzip/zip_file_set_external_attributes.c +++ b/src/Common/libzip/zip_file_set_external_attributes.c @@ -1,6 +1,6 @@ /* zip_file_set_external_attributes.c -- set external attributes for entry - Copyright (C) 2013-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2013-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_file_set_mtime.c b/src/Common/libzip/zip_file_set_mtime.c index f8d6c208..838548ef 100644 --- a/src/Common/libzip/zip_file_set_mtime.c +++ b/src/Common/libzip/zip_file_set_mtime.c @@ -1,6 +1,6 @@ /* zip_file_set_mtime.c -- set modification time of entry. - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -34,9 +34,15 @@ #include "zipint.h" ZIP_EXTERN int +zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) { + time_t mtime; + mtime = _zip_d2u_time(dtime, ddate); + return zip_file_set_mtime(za, idx, mtime, flags); +} + +ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) { zip_entry_t *e; - int changed; if (_zip_get_dirent(za, idx, 0, NULL) == NULL) return -1; @@ -48,27 +54,15 @@ zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) e = za->entry + idx; - changed = e->orig == NULL || mtime != e->orig->last_mod; - - if (changed) { - if (e->changes == NULL) { - if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - e->changes->last_mod = mtime; - e->changes->changed |= ZIP_DIRENT_LAST_MOD; - } - else { - if (e->changes) { - e->changes->changed &= ~ZIP_DIRENT_LAST_MOD; - if (e->changes->changed == 0) { - _zip_dirent_free(e->changes); - e->changes = NULL; - } + if (e->changes == NULL) { + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } } + e->changes->last_mod = mtime; + e->changes->changed |= ZIP_DIRENT_LAST_MOD; + return 0; } diff --git a/src/Common/libzip/zip_file_strerror.c b/src/Common/libzip/zip_file_strerror.c index 189c556c..1fa7fffd 100644 --- a/src/Common/libzip/zip_file_strerror.c +++ b/src/Common/libzip/zip_file_strerror.c @@ -1,6 +1,6 @@ /* zip_file_sterror.c -- get string representation of zip file error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_filerange_crc.c b/src/Common/libzip/zip_filerange_crc.c index 33bf5d85..b8873634 100644 --- a/src/Common/libzip/zip_filerange_crc.c +++ b/src/Common/libzip/zip_filerange_crc.c @@ -1,6 +1,6 @@ /* zip_filerange_crc.c -- compute CRC32 for a range of a file - Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fopen.c b/src/Common/libzip/zip_fopen.c index 4ef76bad..4f1a051d 100644 --- a/src/Common/libzip/zip_fopen.c +++ b/src/Common/libzip/zip_fopen.c @@ -1,6 +1,6 @@ /* zip_fopen.c -- open file in zip archive for reading - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fopen_encrypted.c b/src/Common/libzip/zip_fopen_encrypted.c index 47cd3776..9e9b13e5 100644 --- a/src/Common/libzip/zip_fopen_encrypted.c +++ b/src/Common/libzip/zip_fopen_encrypted.c @@ -1,6 +1,6 @@ /* zip_fopen_encrypted.c -- open file for reading with password - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fopen_index.c b/src/Common/libzip/zip_fopen_index.c index 5f0dc2a7..ffca281d 100644 --- a/src/Common/libzip/zip_fopen_index.c +++ b/src/Common/libzip/zip_fopen_index.c @@ -1,6 +1,6 @@ /* zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fopen_index_encrypted.c b/src/Common/libzip/zip_fopen_index_encrypted.c index 4d4aee39..6712c32a 100644 --- a/src/Common/libzip/zip_fopen_index_encrypted.c +++ b/src/Common/libzip/zip_fopen_index_encrypted.c @@ -1,6 +1,6 @@ /* zip_fopen_index_encrypted.c -- open file for reading by index w/ password - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_fread.c b/src/Common/libzip/zip_fread.c index 3020a16e..646d7124 100644 --- a/src/Common/libzip/zip_fread.c +++ b/src/Common/libzip/zip_fread.c @@ -1,6 +1,6 @@ /* zip_fread.c -- read from file - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_archive_comment.c b/src/Common/libzip/zip_get_archive_comment.c index c51148db..953c6f42 100644 --- a/src/Common/libzip/zip_get_archive_comment.c +++ b/src/Common/libzip/zip_get_archive_comment.c @@ -1,6 +1,6 @@ /* zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_archive_flag.c b/src/Common/libzip/zip_get_archive_flag.c index 1aaca729..fa4dd502 100644 --- a/src/Common/libzip/zip_get_archive_flag.c +++ b/src/Common/libzip/zip_get_archive_flag.c @@ -1,6 +1,6 @@ /* zip_get_archive_flag.c -- get archive global flag - Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_encryption_implementation.c b/src/Common/libzip/zip_get_encryption_implementation.c index 07e43169..c9d52ad5 100644 --- a/src/Common/libzip/zip_get_encryption_implementation.c +++ b/src/Common/libzip/zip_get_encryption_implementation.c @@ -1,6 +1,6 @@ /* zip_get_encryption_implementation.c -- get encryption implementation - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_file_comment.c b/src/Common/libzip/zip_get_file_comment.c index 6e85a58e..f8006861 100644 --- a/src/Common/libzip/zip_get_file_comment.c +++ b/src/Common/libzip/zip_get_file_comment.c @@ -1,6 +1,6 @@ /* zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_name.c b/src/Common/libzip/zip_get_name.c index 2ac005a8..43442093 100644 --- a/src/Common/libzip/zip_get_name.c +++ b/src/Common/libzip/zip_get_name.c @@ -1,6 +1,6 @@ /* zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_num_entries.c b/src/Common/libzip/zip_get_num_entries.c index 99dfc7a6..410d26e1 100644 --- a/src/Common/libzip/zip_get_num_entries.c +++ b/src/Common/libzip/zip_get_num_entries.c @@ -1,6 +1,6 @@ /* zip_get_num_entries.c -- get number of entries in archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_get_num_files.c b/src/Common/libzip/zip_get_num_files.c index b6e910e4..4895eaab 100644 --- a/src/Common/libzip/zip_get_num_files.c +++ b/src/Common/libzip/zip_get_num_files.c @@ -1,6 +1,6 @@ /* zip_get_num_files.c -- get number of files in archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_hash.c b/src/Common/libzip/zip_hash.c index 72884533..3206dbf7 100644 --- a/src/Common/libzip/zip_hash.c +++ b/src/Common/libzip/zip_hash.c @@ -1,6 +1,6 @@ /* zip_hash.c -- hash table string -> uint64 - Copyright (C) 2015-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2015-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_io_util.c b/src/Common/libzip/zip_io_util.c index 53f44377..dd07cbb9 100644 --- a/src/Common/libzip/zip_io_util.c +++ b/src/Common/libzip/zip_io_util.c @@ -1,6 +1,6 @@ /* zip_io_util.c -- I/O helper functions - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_memdup.c b/src/Common/libzip/zip_memdup.c index d6044081..05fcb7b7 100644 --- a/src/Common/libzip/zip_memdup.c +++ b/src/Common/libzip/zip_memdup.c @@ -1,6 +1,6 @@ /* zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_name_locate.c b/src/Common/libzip/zip_name_locate.c index 37b1ffeb..f7318ece 100644 --- a/src/Common/libzip/zip_name_locate.c +++ b/src/Common/libzip/zip_name_locate.c @@ -1,6 +1,6 @@ /* zip_name_locate.c -- get index by name - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_new.c b/src/Common/libzip/zip_new.c index 1cd614df..4f58ecc7 100644 --- a/src/Common/libzip/zip_new.c +++ b/src/Common/libzip/zip_new.c @@ -1,6 +1,6 @@ /* zip_new.c -- create and init struct zip - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_open.c b/src/Common/libzip/zip_open.c index 593bfde5..4e29c5b9 100644 --- a/src/Common/libzip/zip_open.c +++ b/src/Common/libzip/zip_open.c @@ -1,6 +1,6 @@ /* zip_open.c -- open zip archive by name - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -43,8 +43,7 @@ typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, - EXISTS_EMPTY, - EXISTS_NONEMPTY, + EXISTS_OK } exists_t; static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error); static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error); @@ -174,19 +173,16 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { } len = st.size; - /* treat empty files as empty archives */ - if (len == 0) { - if ((za = _zip_allocate_new(src, flags, error)) == NULL) { - return NULL; - } - - return za; - } if ((za = _zip_allocate_new(src, flags, error)) == NULL) { return NULL; } + /* treat empty files as empty archives */ + if (len == 0 && zip_source_accept_empty(src)) { + return za; + } + if ((cdir = _zip_find_central_dir(za, len)) == NULL) { _zip_error_copy(error, &za->error); /* keep src so discard does not get rid of it */ @@ -540,7 +536,7 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) { return EXISTS_ERROR; } - return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY; + return EXISTS_OK; } @@ -725,16 +721,19 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse eocd_disk = _zip_buffer_get_16(buffer); eocd_offset = _zip_buffer_get_64(buffer); - if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) { + /* valid seek value for start of EOCD */ + if (eocd_offset > ZIP_INT64_MAX) { zip_error_set(error, ZIP_ER_SEEK, EFBIG); return NULL; } + /* does EOCD fit before EOCD locator? */ if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) { zip_error_set(error, ZIP_ER_INCONS, 0); return NULL; } + /* make sure current position of buffer is beginning of EOCD */ if (eocd_offset >= buf_offset && eocd_offset + EOCD64LEN <= buf_offset + _zip_buffer_size(buffer)) { _zip_buffer_set_offset(buffer, eocd_offset - buf_offset); free_buffer = false; @@ -758,8 +757,10 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse return NULL; } + /* size of EOCD */ size = _zip_buffer_get_64(buffer); + /* is there a hole between EOCD and EOCD locator, or do they overlap? */ if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) { zip_error_set(error, ZIP_ER_INCONS, 0); if (free_buffer) { @@ -811,6 +812,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse size = _zip_buffer_get_64(buffer); offset = _zip_buffer_get_64(buffer); + /* did we read past the end of the buffer? */ if (!_zip_buffer_ok(buffer)) { zip_error_set(error, ZIP_ER_INTERNAL, 0); if (free_buffer) { @@ -837,6 +839,11 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse return NULL; } + if (nentry > size / CDENTRYSIZE) { + zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + if ((cd = _zip_cdir_new(nentry, error)) == NULL) return NULL; diff --git a/src/Common/libzip/zip_progress.c b/src/Common/libzip/zip_progress.c index 9b116942..d48ae563 100644 --- a/src/Common/libzip/zip_progress.c +++ b/src/Common/libzip/zip_progress.c @@ -1,6 +1,6 @@ /* zip_progress.c -- progress reporting - Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -40,10 +40,14 @@ struct zip_progress { zip_t *za; - zip_progress_callback callback; - void (*ud_free)(void *); - void *ud; + zip_progress_callback callback_progress; + void (*ud_progress_free)(void *); + void *ud_progress; + + zip_cancel_callback callback_cancel; + void (*ud_cancel_free)(void *); + void *ud_cancel; double precision; @@ -54,6 +58,11 @@ struct zip_progress { double end; /* end of sub-progress section */ }; +static void _zip_progress_free_cancel_callback(zip_progress_t *progress); +static void _zip_progress_free_progress_callback(zip_progress_t *progress); +static zip_progress_t *_zip_progress_new(zip_t *za); +static void _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud); +static void _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud); void _zip_progress_end(zip_progress_t *progress) { @@ -67,16 +76,15 @@ _zip_progress_free(zip_progress_t *progress) { return; } - if (progress->ud_free) { - progress->ud_free(progress->ud); - } + _zip_progress_free_progress_callback(progress); + _zip_progress_free_cancel_callback(progress); free(progress); } -zip_progress_t * -_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { +static zip_progress_t * +_zip_progress_new(zip_t *za) { zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress)); if (progress == NULL) { @@ -85,52 +93,117 @@ _zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, v } progress->za = za; - progress->callback = callback; - progress->ud_free = ud_free; - progress->ud = ud; - progress->precision = precision; + + progress->callback_progress = NULL; + progress->ud_progress_free = NULL; + progress->ud_progress = NULL; + progress->precision = 0.0; + + progress->callback_cancel = NULL; + progress->ud_cancel_free = NULL; + progress->ud_cancel = NULL; return progress; } +static void +_zip_progress_free_progress_callback(zip_progress_t *progress) { + if (progress->ud_progress_free) { + progress->ud_progress_free(progress->ud_progress); + } + + progress->callback_progress = NULL; + progress->ud_progress = NULL; + progress->ud_progress_free = NULL; +} + +static void +_zip_progress_free_cancel_callback(zip_progress_t *progress) { + if (progress->ud_cancel_free) { + progress->ud_cancel_free(progress->ud_cancel); + } + + progress->callback_cancel = NULL; + progress->ud_cancel = NULL; + progress->ud_cancel_free = NULL; +} + +static void +_zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { + _zip_progress_free_progress_callback(progress); + + progress->callback_progress = callback; + progress->ud_progress_free = ud_free; + progress->ud_progress = ud; + progress->precision = precision; +} void +_zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) { + _zip_progress_free_cancel_callback(progress); + + progress->callback_cancel = callback; + progress->ud_cancel_free = ud_free; + progress->ud_cancel = ud; +} + +int _zip_progress_start(zip_progress_t *progress) { if (progress == NULL) { - return; + return 0; + } + + if (progress->callback_progress != NULL) { + progress->last_update = 0.0; + progress->callback_progress(progress->za, 0.0, progress->ud_progress); + } + + if (progress->callback_cancel != NULL) { + if (progress->callback_cancel(progress->za, progress->ud_cancel)) { + return -1; + } } - progress->last_update = 0.0; - progress->callback(progress->za, 0.0, progress->ud); + return 0; } -void +int _zip_progress_subrange(zip_progress_t *progress, double start, double end) { if (progress == NULL) { - return; + return 0; } progress->start = start; progress->end = end; - _zip_progress_update(progress, 0.0); + return _zip_progress_update(progress, 0.0); } -void +int _zip_progress_update(zip_progress_t *progress, double sub_current) { double current; if (progress == NULL) { - return; + return 0; } - current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start; + if (progress->callback_progress != NULL) { + current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start; - if (current - progress->last_update > progress->precision) { - progress->callback(progress->za, current, progress->ud); - progress->last_update = current; + if (current - progress->last_update > progress->precision) { + progress->callback_progress(progress->za, current, progress->ud_progress); + progress->last_update = current; + } } + + if (progress->callback_cancel != NULL) { + if (progress->callback_cancel(progress->za, progress->ud_cancel)) { + return -1; + } + } + + return 0; } @@ -139,13 +212,54 @@ zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progr zip_progress_t *progress = NULL; if (callback != NULL) { - if ((progress = _zip_progress_new(za, precision, callback, ud_free, ud)) == NULL) { - return -1; + if (za->progress == NULL) { + if ((za->progress = _zip_progress_new(za)) == NULL) { + return -1; + } } + + _zip_progress_set_progress_callback(za->progress, precision, callback, ud_free, ud); } + else { + if (za->progress != NULL) { + if (za->progress->callback_cancel == NULL) { + _zip_progress_free(za->progress); + za->progress = NULL; + } + else { + _zip_progress_free_progress_callback(za->progress); + } + } + } + + return 0; +} + + +ZIP_EXTERN int +zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) { + zip_progress_t *progress = NULL; + + if (callback != NULL) { + if (za->progress == NULL) { + if ((za->progress = _zip_progress_new(za)) == NULL) { + return -1; + } + } - _zip_progress_free(za->progress); - za->progress = progress; + _zip_progress_set_cancel_callback(za->progress, callback, ud_free, ud); + } + else { + if (za->progress != NULL) { + if (za->progress->callback_progress == NULL) { + _zip_progress_free(za->progress); + za->progress = NULL; + } + else { + _zip_progress_free_cancel_callback(za->progress); + } + } + } return 0; } diff --git a/src/Common/libzip/zip_rename.c b/src/Common/libzip/zip_rename.c index 4fdf6361..e5f16823 100644 --- a/src/Common/libzip/zip_rename.c +++ b/src/Common/libzip/zip_rename.c @@ -1,6 +1,6 @@ /* zip_rename.c -- rename file in zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_replace.c b/src/Common/libzip/zip_replace.c index 2e982aff..30a2eb1d 100644 --- a/src/Common/libzip/zip_replace.c +++ b/src/Common/libzip/zip_replace.c @@ -1,6 +1,6 @@ /* zip_replace.c -- replace file via callback function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_archive_comment.c b/src/Common/libzip/zip_set_archive_comment.c index 166a2c0b..3f050b3e 100644 --- a/src/Common/libzip/zip_set_archive_comment.c +++ b/src/Common/libzip/zip_set_archive_comment.c @@ -1,6 +1,6 @@ /* zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_archive_flag.c b/src/Common/libzip/zip_set_archive_flag.c index facf6146..e0d55021 100644 --- a/src/Common/libzip/zip_set_archive_flag.c +++ b/src/Common/libzip/zip_set_archive_flag.c @@ -1,6 +1,6 @@ /* zip_get_archive_flag.c -- set archive global flag - Copyright (C) 2008-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_default_password.c b/src/Common/libzip/zip_set_default_password.c index 8081657c..41c7c519 100644 --- a/src/Common/libzip/zip_set_default_password.c +++ b/src/Common/libzip/zip_set_default_password.c @@ -1,6 +1,6 @@ /* zip_set_default_password.c -- set default password for decryption - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_file_comment.c b/src/Common/libzip/zip_set_file_comment.c index e4e0331e..1fa01ae6 100644 --- a/src/Common/libzip/zip_set_file_comment.c +++ b/src/Common/libzip/zip_set_file_comment.c @@ -1,6 +1,6 @@ /* zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_file_compression.c b/src/Common/libzip/zip_set_file_compression.c index 054dd1fd..927fbb76 100644 --- a/src/Common/libzip/zip_set_file_compression.c +++ b/src/Common/libzip/zip_set_file_compression.c @@ -1,6 +1,6 @@ /* zip_set_file_compression.c -- set compression for file in archive - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_set_name.c b/src/Common/libzip/zip_set_name.c index aa1dd8ea..43c772e4 100644 --- a/src/Common/libzip/zip_set_name.c +++ b/src/Common/libzip/zip_set_name.c @@ -1,6 +1,6 @@ /* zip_set_name.c -- rename helper function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_accept_empty.c b/src/Common/libzip/zip_source_accept_empty.c new file mode 100644 index 00000000..e6d51516 --- /dev/null +++ b/src/Common/libzip/zip_source_accept_empty.c @@ -0,0 +1,52 @@ +/* + zip_source_accept_empty.c -- if empty source is a valid archive + Copyright (C) 2019 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <libzip@nih.at> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "zipint.h" + + +bool +zip_source_accept_empty(zip_source_t *src) { + int ret; + + if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY)) == 0) { + if (ZIP_SOURCE_IS_LAYERED(src)) { + return zip_source_accept_empty(src->src); + } + return true; + } + + ret = (int)_zip_source_call(src, NULL, 0, ZIP_SOURCE_ACCEPT_EMPTY); + + return ret != 0; +} diff --git a/src/Common/libzip/zip_source_begin_write.c b/src/Common/libzip/zip_source_begin_write.c index a8b90b5f..432c2c15 100644 --- a/src/Common/libzip/zip_source_begin_write.c +++ b/src/Common/libzip/zip_source_begin_write.c @@ -1,6 +1,6 @@ /* zip_source_begin_write.c -- start a new file for writing - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_begin_write_cloning.c b/src/Common/libzip/zip_source_begin_write_cloning.c index b38de04d..41b4c73c 100644 --- a/src/Common/libzip/zip_source_begin_write_cloning.c +++ b/src/Common/libzip/zip_source_begin_write_cloning.c @@ -1,6 +1,6 @@ /* zip_source_begin_write_cloning.c -- clone part of file for writing - Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_buffer.c b/src/Common/libzip/zip_source_buffer.c index 119bc02c..0685fb39 100644 --- a/src/Common/libzip/zip_source_buffer.c +++ b/src/Common/libzip/zip_source_buffer.c @@ -1,6 +1,6 @@ /* zip_source_buffer.c -- create zip data source from buffer - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -93,9 +93,13 @@ ZIP_EXTERN zip_source_t * zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) { zip_buffer_fragment_t fragment; - if (data == NULL && len > 0) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; + if (data == NULL) { + if (len > 0) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + return zip_source_buffer_fragment_create(NULL, 0, freep, error); } fragment.data = (zip_uint8_t *)data; @@ -457,7 +461,7 @@ buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int } buffer->nfragments = j; buffer->first_owned_fragment = free_data ? 0 : buffer->nfragments; - buffer->fragment_offsets[nfragments] = offset; + buffer->fragment_offsets[buffer->nfragments] = offset; buffer->size = offset; } diff --git a/src/Common/libzip/zip_source_call.c b/src/Common/libzip/zip_source_call.c index 3f374fc5..e7c29544 100644 --- a/src/Common/libzip/zip_source_call.c +++ b/src/Common/libzip/zip_source_call.c @@ -1,6 +1,6 @@ /* zip_source_call.c -- invoke callback command on zip_source - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_close.c b/src/Common/libzip/zip_source_close.c index 79165500..ab7898ce 100644 --- a/src/Common/libzip/zip_source_close.c +++ b/src/Common/libzip/zip_source_close.c @@ -1,6 +1,6 @@ /* zip_source_close.c -- close zip_source (stop reading) - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_commit_write.c b/src/Common/libzip/zip_source_commit_write.c index 67881f05..d1254bf1 100644 --- a/src/Common/libzip/zip_source_commit_write.c +++ b/src/Common/libzip/zip_source_commit_write.c @@ -1,6 +1,6 @@ /* zip_source_commit_write.c -- commit changes to file - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_compress.c b/src/Common/libzip/zip_source_compress.c index d2ae220c..59b1212d 100644 --- a/src/Common/libzip/zip_source_compress.c +++ b/src/Common/libzip/zip_source_compress.c @@ -1,6 +1,6 @@ /* zip_source_compress.c -- (de)compression routines - Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -67,6 +67,16 @@ static struct implementation implementations[] = { #if defined(HAVE_LIBBZ2) {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress}, #endif +#if defined(HAVE_LIBLZMA) +/* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2 + archives made this way - and vice versa. + + {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, + {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, +*/ + {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress}, +#endif + }; static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]); diff --git a/src/Common/libzip/zip_source_crc.c b/src/Common/libzip/zip_source_crc.c index e16f9298..56572c0b 100644 --- a/src/Common/libzip/zip_source_crc.c +++ b/src/Common/libzip/zip_source_crc.c @@ -1,6 +1,6 @@ /* zip_source_crc.c -- pass-through source that calculates CRC32 and size - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_error.c b/src/Common/libzip/zip_source_error.c index 1e0e0d46..2257f715 100644 --- a/src/Common/libzip/zip_source_error.c +++ b/src/Common/libzip/zip_source_error.c @@ -1,6 +1,6 @@ /* zip_source_error.c -- get last error from zip_source - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_file.c b/src/Common/libzip/zip_source_file.c index 87147852..3fff4e3b 100644 --- a/src/Common/libzip/zip_source_file.c +++ b/src/Common/libzip/zip_source_file.c @@ -1,6 +1,6 @@ /* zip_source_file.c -- create data source from file - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_filep.c b/src/Common/libzip/zip_source_filep.c index cb3d1511..30e5991c 100644 --- a/src/Common/libzip/zip_source_filep.c +++ b/src/Common/libzip/zip_source_filep.c @@ -31,6 +31,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -54,28 +55,6 @@ #define CAN_CLONE #endif -#ifdef _WIN32 -/* WIN32 needs <fcntl.h> for _O_BINARY */ -#include <fcntl.h> -#endif - -/* Windows sys/types.h does not provide these */ -#ifndef S_ISREG -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#endif -#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO) -#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO) -#elif defined(_S_IWRITE) -#define _SAFE_MASK (_S_IWRITE) -#else -#error do not know safe values for umask, please report this -#endif - -#ifdef _MSC_VER -/* MSVC doesn't have mode_t */ -typedef int mode_t; -#endif - struct read_file { zip_error_t error; /* last error information */ zip_int64_t supports; @@ -99,6 +78,7 @@ static int create_temp_output(struct read_file *ctx); #ifdef CAN_CLONE static zip_int64_t create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset); #endif +static FILE *_zip_fopen(const char *name, bool writeable); static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error); static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error); @@ -225,6 +205,7 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int } } + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); #ifdef CAN_CLONE if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) { ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING); @@ -245,23 +226,29 @@ static int create_temp_output(struct read_file *ctx) { char *temp; int tfd; - mode_t mask; + int mode; FILE *tfp; + struct stat st; if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); return -1; } + + if (stat(ctx->fname, &st) == 0) { + mode = st.st_mode; + } + else { + mode = -1; + } + sprintf(temp, "%s.XXXXXX", ctx->fname); - mask = umask(_SAFE_MASK); - if ((tfd = mkstemp(temp)) == -1) { + if ((tfd = _zip_mkstempm(temp, mode)) == -1) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - umask(mask); free(temp); return -1; } - umask(mask); if ((tfp = fdopen(tfd, "r+b")) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); @@ -271,14 +258,6 @@ create_temp_output(struct read_file *ctx) { return -1; } -#ifdef _WIN32 - /* - According to Pierre Joye, Windows in some environments per - default creates text files, so force binary mode. - */ - _setmode(_fileno(tfp), _O_BINARY); -#endif - ctx->fout = tfp; ctx->tmpname = temp; @@ -316,7 +295,7 @@ zip_int64_t static create_temp_output_cloning(struct read_file *ctx, zip_uint64_ free(temp); return -1; } - if ((tfp = fopen(temp, "r+b")) == NULL) { + if ((tfp = _zip_fopen(temp, true)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); (void)remove(temp); free(temp); @@ -396,12 +375,19 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { buf = (char *)data; switch (cmd) { + case ZIP_SOURCE_ACCEPT_EMPTY: + return 0; + case ZIP_SOURCE_BEGIN_WRITE: +#ifdef _WIN32 + return -1; +#else if (ctx->fname == NULL) { zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); return -1; } return create_temp_output(ctx); +#endif #ifdef CAN_CLONE case ZIP_SOURCE_BEGIN_WRITE_CLONING: @@ -412,40 +398,28 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { return create_temp_output_cloning(ctx, len); #endif - case ZIP_SOURCE_COMMIT_WRITE: { - mode_t mode; - struct stat st; + case ZIP_SOURCE_CLOSE: + if (ctx->fname) { + fclose(ctx->f); + ctx->f = NULL; + } + return 0; + case ZIP_SOURCE_COMMIT_WRITE: { if (fclose(ctx->fout) < 0) { ctx->fout = NULL; zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); } ctx->fout = NULL; - if (stat(ctx->fname, &st) == 0) { - mode = st.st_mode; - } else { - mode_t mask = umask(022); - umask(mask); - mode = 0666 & ~mask; - } if (rename(ctx->tmpname, ctx->fname) < 0) { zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); return -1; } - /* not much we can do if chmod fails except make the whole commit fail */ - (void)chmod(ctx->fname, mode); free(ctx->tmpname); ctx->tmpname = NULL; return 0; } - case ZIP_SOURCE_CLOSE: - if (ctx->fname) { - fclose(ctx->f); - ctx->f = NULL; - } - return 0; - case ZIP_SOURCE_ERROR: return zip_error_to_data(&ctx->error, data, len); @@ -459,7 +433,7 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { case ZIP_SOURCE_OPEN: if (ctx->fname) { - if ((ctx->f = fopen(ctx->fname, "rb")) == NULL) { + if ((ctx->f = _zip_fopen(ctx->fname, false)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); return -1; } @@ -656,3 +630,34 @@ _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error) { } return 0; } + + +/* + * fopen replacement that sets the close-on-exec flag + * some implementations support an fopen 'e' flag for that, + * but e.g. macOS doesn't. + */ +static FILE * +_zip_fopen(const char *name, bool writeable) +{ + int fd; + int flags; + FILE *fp; + + flags = O_CLOEXEC; + if (writeable) { + flags |= O_RDWR; + } + else { + flags |= O_RDONLY; + } + + /* mode argument needed on Windows */ + if ((fd = open(name, flags, 0666)) < 0) { + return NULL; + } + if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) { + return NULL; + } + return fp; +} diff --git a/src/Common/libzip/zip_source_free.c b/src/Common/libzip/zip_source_free.c index dd3c6df9..2f10ef8f 100644 --- a/src/Common/libzip/zip_source_free.c +++ b/src/Common/libzip/zip_source_free.c @@ -1,6 +1,6 @@ /* zip_source_free.c -- free zip data source - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_function.c b/src/Common/libzip/zip_source_function.c index c9730c95..d5c1b5b0 100644 --- a/src/Common/libzip/zip_source_function.c +++ b/src/Common/libzip/zip_source_function.c @@ -1,6 +1,6 @@ /* zip_source_function.c -- create zip data source from callback function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_get_compression_flags.c b/src/Common/libzip/zip_source_get_compression_flags.c index a9442aa5..7e04bed6 100644 --- a/src/Common/libzip/zip_source_get_compression_flags.c +++ b/src/Common/libzip/zip_source_get_compression_flags.c @@ -1,6 +1,6 @@ /* zip_source_get_compression_flags.c -- get compression flags for entry - Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_is_deleted.c b/src/Common/libzip/zip_source_is_deleted.c index 090a67b4..edd10ca2 100644 --- a/src/Common/libzip/zip_source_is_deleted.c +++ b/src/Common/libzip/zip_source_is_deleted.c @@ -1,6 +1,6 @@ /* zip_source_is_deleted.c -- was archive was removed? - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_layered.c b/src/Common/libzip/zip_source_layered.c index 580bff0e..d02bc852 100644 --- a/src/Common/libzip/zip_source_layered.c +++ b/src/Common/libzip/zip_source_layered.c @@ -1,6 +1,6 @@ /* zip_source_layered.c -- create layered source - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_open.c b/src/Common/libzip/zip_source_open.c index d10a3c55..414c677a 100644 --- a/src/Common/libzip/zip_source_open.c +++ b/src/Common/libzip/zip_source_open.c @@ -1,6 +1,6 @@ /* zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_pkware.c b/src/Common/libzip/zip_source_pkware.c index cc510ea5..1b59d7a7 100644 --- a/src/Common/libzip/zip_source_pkware.c +++ b/src/Common/libzip/zip_source_pkware.c @@ -1,6 +1,6 @@ /* zip_source_pkware.c -- Traditional PKWARE de/encryption routines - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_read.c b/src/Common/libzip/zip_source_read.c index 816fb3d2..33088cb1 100644 --- a/src/Common/libzip/zip_source_read.c +++ b/src/Common/libzip/zip_source_read.c @@ -1,6 +1,6 @@ /* zip_source_read.c -- read data from zip_source - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_remove.c b/src/Common/libzip/zip_source_remove.c index 6841b747..14eddb8f 100644 --- a/src/Common/libzip/zip_source_remove.c +++ b/src/Common/libzip/zip_source_remove.c @@ -1,6 +1,6 @@ /* zip_source_remove.c -- remove empty archive - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_rollback_write.c b/src/Common/libzip/zip_source_rollback_write.c index 04aa9389..e8259bff 100644 --- a/src/Common/libzip/zip_source_rollback_write.c +++ b/src/Common/libzip/zip_source_rollback_write.c @@ -1,6 +1,6 @@ /* zip_source_rollback_write.c -- discard changes - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_seek.c b/src/Common/libzip/zip_source_seek.c index c7bd8e6e..163daf1b 100644 --- a/src/Common/libzip/zip_source_seek.c +++ b/src/Common/libzip/zip_source_seek.c @@ -1,6 +1,6 @@ /* zip_source_seek.c -- seek to offset - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_seek_write.c b/src/Common/libzip/zip_source_seek_write.c index a20dc82e..6b0aa78e 100644 --- a/src/Common/libzip/zip_source_seek_write.c +++ b/src/Common/libzip/zip_source_seek_write.c @@ -1,6 +1,6 @@ /* zip_source_seek_write.c -- seek to offset for writing - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_stat.c b/src/Common/libzip/zip_source_stat.c index f3af3be9..3421d2cb 100644 --- a/src/Common/libzip/zip_source_stat.c +++ b/src/Common/libzip/zip_source_stat.c @@ -1,6 +1,6 @@ /* zip_source_stat.c -- get meta information from zip_source - Copyright (C) 2009-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_supports.c b/src/Common/libzip/zip_source_supports.c index 394f06ec..84715598 100644 --- a/src/Common/libzip/zip_source_supports.c +++ b/src/Common/libzip/zip_source_supports.c @@ -1,6 +1,6 @@ /* zip_source_supports.c -- check for supported functions - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_tell.c b/src/Common/libzip/zip_source_tell.c index da13cf51..772e2524 100644 --- a/src/Common/libzip/zip_source_tell.c +++ b/src/Common/libzip/zip_source_tell.c @@ -1,6 +1,6 @@ /* zip_source_tell.c -- report current offset - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_tell_write.c b/src/Common/libzip/zip_source_tell_write.c index d20139fe..96ad7e26 100644 --- a/src/Common/libzip/zip_source_tell_write.c +++ b/src/Common/libzip/zip_source_tell_write.c @@ -1,6 +1,6 @@ /* zip_source_tell_write.c -- report current offset for writing - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_win32a.c b/src/Common/libzip/zip_source_win32a.c index b4b060a8..257fc6aa 100644 --- a/src/Common/libzip/zip_source_win32a.c +++ b/src/Common/libzip/zip_source_win32a.c @@ -1,6 +1,6 @@ /* zip_source_win32a.c -- create data source from Windows file (ANSI) - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -112,8 +112,18 @@ _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32 static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx) { + DWORD attributes = GetFileAttributesA(ctx->tmpname); + if (INVALID_FILE_ATTRIBUTES == attributes) + return -1; + + if (FILE_ATTRIBUTE_TEMPORARY & attributes) { + if (!SetFileAttributesA(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) + return -1; + } + if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) return -1; + return 0; } diff --git a/src/Common/libzip/zip_source_win32handle.c b/src/Common/libzip/zip_source_win32handle.c index 3a2f52e1..8746cdd1 100644 --- a/src/Common/libzip/zip_source_win32handle.c +++ b/src/Common/libzip/zip_source_win32handle.c @@ -1,6 +1,6 @@ /* zip_source_win32file.c -- create data source from HANDLE (Win32) - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -127,6 +127,8 @@ _zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; } + ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY); + if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) { free(ctx->fname); free(ctx); @@ -148,6 +150,9 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd buf = (char *)data; switch (cmd) { + case ZIP_SOURCE_ACCEPT_EMPTY: + return 0; + case ZIP_SOURCE_BEGIN_WRITE: if (ctx->fname == NULL) { zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); @@ -261,7 +266,7 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd switch (args->whence) { case SEEK_SET: - new_current = args->offset; + new_current = args->offset + ctx->start; break; case SEEK_END: diff --git a/src/Common/libzip/zip_source_win32utf8.c b/src/Common/libzip/zip_source_win32utf8.c index 103b498c..083f5bcb 100644 --- a/src/Common/libzip/zip_source_win32utf8.c +++ b/src/Common/libzip/zip_source_win32utf8.c @@ -1,6 +1,6 @@ /* zip_source_win32utf8.c -- create data source from Windows file (UTF-8) - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_win32w.c b/src/Common/libzip/zip_source_win32w.c index 4097214d..cb8d64e6 100644 --- a/src/Common/libzip/zip_source_win32w.c +++ b/src/Common/libzip/zip_source_win32w.c @@ -1,6 +1,6 @@ /* zip_source_win32w.c -- create data source from Windows file (UTF-16) - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -136,8 +136,18 @@ _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32 static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) { + DWORD attributes = GetFileAttributesW(ctx->tmpname); + if (INVALID_FILE_ATTRIBUTES == attributes) + return -1; + + if (FILE_ATTRIBUTE_TEMPORARY & attributes) { + if (!SetFileAttributesW(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) + return -1; + } + if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) return -1; + return 0; } diff --git a/src/Common/libzip/zip_source_window.c b/src/Common/libzip/zip_source_window.c index d9e90bff..1276485d 100644 --- a/src/Common/libzip/zip_source_window.c +++ b/src/Common/libzip/zip_source_window.c @@ -1,6 +1,6 @@ /* zip_source_window.c -- return part of lower source - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_write.c b/src/Common/libzip/zip_source_write.c index 9f494e09..73fc3a31 100644 --- a/src/Common/libzip/zip_source_write.c +++ b/src/Common/libzip/zip_source_write.c @@ -1,6 +1,6 @@ /* zip_source_write.c -- start a new file for writing - Copyright (C) 2014-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_zip.c b/src/Common/libzip/zip_source_zip.c index 3fd90abe..1f77aaaf 100644 --- a/src/Common/libzip/zip_source_zip.c +++ b/src/Common/libzip/zip_source_zip.c @@ -1,6 +1,6 @@ /* zip_source_zip.c -- create data source from zip file - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_source_zip_new.c b/src/Common/libzip/zip_source_zip_new.c index ab785615..f36609b1 100644 --- a/src/Common/libzip/zip_source_zip_new.c +++ b/src/Common/libzip/zip_source_zip_new.c @@ -1,6 +1,6 @@ /* zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_stat.c b/src/Common/libzip/zip_stat.c index 237d985d..341c6f77 100644 --- a/src/Common/libzip/zip_stat.c +++ b/src/Common/libzip/zip_stat.c @@ -1,6 +1,6 @@ /* zip_stat.c -- get information about file by name - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_stat_index.c b/src/Common/libzip/zip_stat_index.c index d19e76a3..71f80491 100644 --- a/src/Common/libzip/zip_stat_index.c +++ b/src/Common/libzip/zip_stat_index.c @@ -1,6 +1,6 @@ /* zip_stat_index.c -- get information about file by index - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -48,10 +48,17 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) { - if (zip_source_stat(za->entry[index].source, st) < 0) { + zip_entry_t *entry = za->entry+index; + + if (zip_source_stat(entry->source, st) < 0) { zip_error_set(&za->error, ZIP_ER_CHANGED, 0); return -1; } + + if (entry->changes->changed & ZIP_DIRENT_LAST_MOD) { + st->mtime = de->last_mod; + st->valid |= ZIP_STAT_MTIME; + } } else { zip_stat_init(st); diff --git a/src/Common/libzip/zip_stat_init.c b/src/Common/libzip/zip_stat_init.c index 46fa404c..6d0903d6 100644 --- a/src/Common/libzip/zip_stat_init.c +++ b/src/Common/libzip/zip_stat_init.c @@ -1,6 +1,6 @@ /* zip_stat_init.c -- initialize struct zip_stat. - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_strerror.c b/src/Common/libzip/zip_strerror.c index eb94198d..906c7f76 100644 --- a/src/Common/libzip/zip_strerror.c +++ b/src/Common/libzip/zip_strerror.c @@ -1,6 +1,6 @@ /* zip_sterror.c -- get string representation of zip error - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_string.c b/src/Common/libzip/zip_string.c index 7e16a728..a6edbc5d 100644 --- a/src/Common/libzip/zip_string.c +++ b/src/Common/libzip/zip_string.c @@ -1,6 +1,6 @@ /* zip_string.c -- string handling (with encoding) - Copyright (C) 2012-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_unchange.c b/src/Common/libzip/zip_unchange.c index 8285707b..1a78e2c3 100644 --- a/src/Common/libzip/zip_unchange.c +++ b/src/Common/libzip/zip_unchange.c @@ -1,6 +1,6 @@ /* zip_unchange.c -- undo changes to file in zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_unchange_all.c b/src/Common/libzip/zip_unchange_all.c index 6a43358c..5e7df80a 100644 --- a/src/Common/libzip/zip_unchange_all.c +++ b/src/Common/libzip/zip_unchange_all.c @@ -1,6 +1,6 @@ /* zip_unchange.c -- undo changes to all files in zip archive - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_unchange_archive.c b/src/Common/libzip/zip_unchange_archive.c index 404f1ed8..bd223ef5 100644 --- a/src/Common/libzip/zip_unchange_archive.c +++ b/src/Common/libzip/zip_unchange_archive.c @@ -1,6 +1,6 @@ /* zip_unchange_archive.c -- undo global changes to ZIP archive - Copyright (C) 2006-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_unchange_data.c b/src/Common/libzip/zip_unchange_data.c index f1df2bde..74a429c9 100644 --- a/src/Common/libzip/zip_unchange_data.c +++ b/src/Common/libzip/zip_unchange_data.c @@ -1,6 +1,6 @@ /* zip_unchange_data.c -- undo helper function - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zip_utf-8.c b/src/Common/libzip/zip_utf-8.c index 684eba5e..099db9bf 100644 --- a/src/Common/libzip/zip_utf-8.c +++ b/src/Common/libzip/zip_utf-8.c @@ -1,6 +1,6 @@ /* zip_utf-8.c -- UTF-8 support functions for libzip - Copyright (C) 2011-2018 Dieter Baron and Thomas Klausner + Copyright (C) 2011-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> diff --git a/src/Common/libzip/zipint.h b/src/Common/libzip/zipint.h index 093a1b2d..721d36e8 100644 --- a/src/Common/libzip/zipint.h +++ b/src/Common/libzip/zipint.h @@ -3,7 +3,7 @@ /* zipint.h -- internal declarations. - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> @@ -150,6 +150,9 @@ extern zip_compression_algorithm_t zip_algorithm_bzip2_compress; extern zip_compression_algorithm_t zip_algorithm_bzip2_decompress; extern zip_compression_algorithm_t zip_algorithm_deflate_compress; extern zip_compression_algorithm_t zip_algorithm_deflate_decompress; +extern zip_compression_algorithm_t zip_algorithm_xz_compress; +extern zip_compression_algorithm_t zip_algorithm_xz_decompress; + bool zip_compression_method_supported(zip_int32_t method, bool compress); @@ -468,6 +471,7 @@ void _zip_cdir_free(zip_cdir_t *); bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error); zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *); zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors); +time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); void _zip_deregister_source(zip_t *za, zip_source_t *src); zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *); @@ -523,16 +527,19 @@ zip_hash_t *_zip_hash_new(zip_error_t *error); bool _zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error); bool _zip_hash_revert(zip_hash_t *hash, zip_error_t *error); +int _zip_mkstempm(char *path, int mode); + zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *); void _zip_progress_end(zip_progress_t *progress); void _zip_progress_free(zip_progress_t *progress); -zip_progress_t *_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud); -void _zip_progress_start(zip_progress_t *progress); -void _zip_progress_subrange(zip_progress_t *progress, double start, double end); -void _zip_progress_update(zip_progress_t *progress, double value); +int _zip_progress_start(zip_progress_t *progress); +int _zip_progress_subrange(zip_progress_t *progress, double start, double end); +int _zip_progress_update(zip_progress_t *progress, double value); -ZIP_EXTERN bool zip_random(zip_uint8_t *buffer, zip_uint16_t length); +/* this symbol is extern so it can be overridden for regression testing */ +ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length); +zip_uint32_t zip_random_uint32(void); int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error); int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error); @@ -543,6 +550,7 @@ int _zip_register_source(zip_t *za, zip_source_t *src); void _zip_set_open_error(int *zep, const zip_error_t *err, int ze); +bool zip_source_accept_empty(zip_source_t *src); zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command); bool _zip_source_eof(zip_source_t *); zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error); diff --git a/src/Common/libzip/zipwin32.h b/src/Common/libzip/zipwin32.h index 7d3ac76c..870f1d5a 100644 --- a/src/Common/libzip/zipwin32.h +++ b/src/Common/libzip/zipwin32.h @@ -3,7 +3,7 @@ /* zipwin32.h -- internal declarations for Windows. - Copyright (C) 1999-2018 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at <libzip@nih.at> |