diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2018-03-18 23:13:40 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2018-03-18 23:13:40 +0100 |
commit | cd7a01c34fc4304ef8161ee617568f274ace5d24 (patch) | |
tree | 41ed56e75a5feedc5f7d4fedb6338569d54d6076 | |
parent | 49a8e52139b960afd3913053380190cf2d03ceda (diff) | |
download | VeraCrypt-cd7a01c34fc4304ef8161ee617568f274ace5d24.tar.gz VeraCrypt-cd7a01c34fc4304ef8161ee617568f274ace5d24.zip |
Windows: Update libzip to version 1.5.0 that include fixes for some security issues.
118 files changed, 4699 insertions, 3477 deletions
diff --git a/src/Common/Zip.vcxproj b/src/Common/Zip.vcxproj index 15604833..746f771d 100644 --- a/src/Common/Zip.vcxproj +++ b/src/Common/Zip.vcxproj @@ -25,2 +25,3 @@ <ClCompile Include="libzip\zip_add_entry.c" /> + <ClCompile Include="libzip\zip_algorithm_deflate.c" /> <ClCompile Include="libzip\zip_buffer.c" /> @@ -62,3 +63,2 @@ <ClCompile Include="libzip\zip_get_archive_flag.c" /> - <ClCompile Include="libzip\zip_get_compression_implementation.c" /> <ClCompile Include="libzip\zip_get_encryption_implementation.c" /> @@ -74,2 +74,3 @@ <ClCompile Include="libzip\zip_open.c" /> + <ClCompile Include="libzip\zip_progress.c" /> <ClCompile Include="libzip\zip_rename.c" /> @@ -83,2 +84,3 @@ <ClCompile Include="libzip\zip_source_begin_write.c" /> + <ClCompile Include="libzip\zip_source_begin_write_cloning.c" /> <ClCompile Include="libzip\zip_source_buffer.c" /> @@ -87,2 +89,3 @@ <ClCompile Include="libzip\zip_source_commit_write.c" /> + <ClCompile Include="libzip\zip_source_compress.c" /> <ClCompile Include="libzip\zip_source_crc.c" /> @@ -93,2 +96,3 @@ <ClCompile Include="libzip\zip_source_function.c" /> + <ClCompile Include="libzip\zip_source_get_compression_flags.c" /> <ClCompile Include="libzip\zip_source_is_deleted.c" /> diff --git a/src/Common/Zip.vcxproj.filters b/src/Common/Zip.vcxproj.filters index 651be91e..fa83631a 100644 --- a/src/Common/Zip.vcxproj.filters +++ b/src/Common/Zip.vcxproj.filters @@ -134,5 +134,2 @@ </ClCompile> - <ClCompile Include="libzip\zip_get_compression_implementation.c"> - <Filter>libzip</Filter> - </ClCompile> <ClCompile Include="libzip\zip_get_encryption_implementation.c"> @@ -350,2 +347,17 @@ </ClCompile> + <ClCompile Include="libzip\zip_progress.c"> + <Filter>libzip</Filter> + </ClCompile> + <ClCompile Include="libzip\zip_source_begin_write_cloning.c"> + <Filter>libzip</Filter> + </ClCompile> + <ClCompile Include="libzip\zip_source_compress.c"> + <Filter>libzip</Filter> + </ClCompile> + <ClCompile Include="libzip\zip_algorithm_deflate.c"> + <Filter>libzip</Filter> + </ClCompile> + <ClCompile Include="libzip\zip_source_get_compression_flags.c"> + <Filter>libzip</Filter> + </ClCompile> </ItemGroup> diff --git a/src/Common/libzip/LICENSE b/src/Common/libzip/LICENSE index 1c2e86bf..e93454e8 100644 --- a/src/Common/libzip/LICENSE +++ b/src/Common/libzip/LICENSE @@ -1,2 +1,2 @@ -Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner +Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -31,36 +31 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -For AES encryption support, files under the following license are used: - ---------------------------------------------------------------------------- -Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. -All rights reserved. - -LICENSE TERMS - -The free distribution and use of this software in both source and binary -form is allowed (with or without changes) provided that: - - 1. distributions of this source code include the above copyright - notice, this list of conditions and the following disclaimer; - - 2. distributions in binary form include the above copyright - notice, this list of conditions and the following disclaimer - in the documentation and/or other associated materials; - - 3. the copyright holder's name is not used to endorse products - built using this software without specific written permission. - -ALTERNATIVELY, provided that this notice is retained in full, this product -may be distributed under the terms of the GNU General Public License (GPL), -in which case the provisions of the GPL apply INSTEAD OF those given above. - -DISCLAIMER - -This software is provided 'as is' with no explicit or implied warranties -in respect of its properties, including, but not limited to, correctness -and/or fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 18th November 2008 diff --git a/src/Common/libzip/NEWS.md b/src/Common/libzip/NEWS.md index 97bf2dea..a4bc5f9b 100644 --- a/src/Common/libzip/NEWS.md +++ b/src/Common/libzip/NEWS.md @@ -1 +1,39 @@ +1.5.0 [2018-03-11] +================== + +* Use standard cryptographic library instead of custom AES implementation. + This also simplifies the license. +* Use `clang-format` to format the source code. +* More Windows improvements. + +1.4.0 [2017-12-29] +================== + +* Improve build with cmake +* Retire autoconf/automake build system +* Add `zip_source_buffer_fragment()`. +* Add support to clone unchanged beginning of archive (instead of rewriting it). + Supported for buffer sources and on Apple File System. +* Add support for Microsoft Universal Windows Platform. + +1.3.2 [2017-11-20] +================== +* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed. + +1.3.1 [2017-11-19] +================== + +* Install zipconf.h into ${PREFIX}/include +* Add zip_libzip_version() +* Fix AES tests on Linux + +1.3.0 [2017-09-02] +================== + +* Support bzip2 compressed zip archives +* Improve file progress callback code +* Fix zip_fdopen() +* CVE-2017-12858: Fix double free() +* CVE-2017-14107: Improve EOCD64 parsing + 1.2.0 [2017-02-19] @@ -4,7 +42,7 @@ * Support for AES encryption (Winzip version), both encryption - and decryption. -* Support legacy zip files with >64k entries. -* Fix seeking in zip_source_file if start > 0. -* Add zip_fseek() for seeking in uncompressed data. -* Add zip_ftell() for telling position in uncompressed data. + and decryption +* Support legacy zip files with >64k entries +* Fix seeking in zip_source_file if start > 0 +* Add zip_fseek() for seeking in uncompressed data +* Add zip_ftell() for telling position in uncompressed data * Add zip_register_progress_callback() for UI updates during zip_close() @@ -14,3 +52,3 @@ -* Fix build on Windows when using autoconf. +* Fix build on Windows when using autoconf @@ -42,3 +80,3 @@ -* Build fixes for Windows. +* Build fixes for Windows @@ -47,10 +85,10 @@ -* Implemented an I/O abstraction layer. -* Added support for native Windows API for files. -* Added support for setting the last modification time for a file. -* Added a new type zip_error_t for errors. -* Added more typedefs for structs. -* Torrentzip support was removed. -* CVE-2015-2331 was fixed. -* Addressed all Coverity CIDs. +* Implemented an I/O abstraction layer +* Added support for native Windows API for files +* Added support for setting the last modification time for a file +* Added a new type zip_error_t for errors +* Added more typedefs for structs +* Torrentzip support was removed +* CVE-2015-2331 was fixed +* Addressed all Coverity CIDs @@ -59,6 +97,6 @@ -* Support querying/setting operating system and external attributes. +* Support querying/setting operating system and external attributes * For newly added files, set operating system to UNIX, permissions - to 0666 (0777 for directories). -* Fix bug when writing zip archives containing files bigger than 4GB. + to 0666 (0777 for directories) +* Fix bug when writing zip archives containing files bigger than 4GB @@ -67,4 +105,4 @@ -* Fix bugs in zip_set_file_compression(). -* Include Xcode build infrastructure. +* Fix bugs in zip_set_file_compression() +* Include Xcode build infrastructure @@ -94,7 +132,7 @@ -* Added zip_get_num_entries(), deprecated zip_get_num_files(). -* Better windows support. -* Support for traditional PKWARE encryption added. -* Fix opening archives with more than 65535 entries. -* Fix some memory leaks. +* Added zip_get_num_entries(), deprecated zip_get_num_files() +* Better windows support +* Support for traditional PKWARE encryption added +* Fix opening archives with more than 65535 entries +* Fix some memory leaks * Fix cmake build and installation @@ -102,3 +140,3 @@ * Fixed CVE-2011-0421 (no security implications though) -* More documentation. +* More documentation @@ -107,3 +145,3 @@ -* Include m4/ directory in distribution; some packagers need it. +* Include m4/ directory in distribution; some packagers need it @@ -112,4 +150,4 @@ -* Avoid passing uninitialized data to deflate(). -* Fix memory leak when closing zip archives. +* Avoid passing uninitialized data to deflate() +* Fix memory leak when closing zip archives @@ -118,6 +156,6 @@ -* Fix infinite loop on reading some broken files. -* Optimization in time conversion (don't call localtime()). -* Clear data descriptor flag in central directory, fixing Open Office files. -* Allow more than 64k entries. +* Fix infinite loop on reading some broken files +* Optimization in time conversion (don't call localtime()) +* Clear data descriptor flag in central directory, fixing Open Office files +* Allow more than 64k entries @@ -153,3 +191,3 @@ * shared library major bump because of previous two -* added functions for reading and writing file and archive comments. +* added functions for reading and writing file and archive comments New functions: zip_get_archive_comment, zip_get_file_comment, diff --git a/src/Common/libzip/compat.h b/src/Common/libzip/compat.h index dc73f5ce..7604d969 100644 --- a/src/Common/libzip/compat.h +++ b/src/Common/libzip/compat.h @@ -5,3 +5,3 @@ compat.h -- compatibility defines. - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -22,3 +22,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -36,2 +36,4 @@ +#include "zipconf.h" + #ifdef HAVE_CONFIG_H @@ -44,6 +46,8 @@ #ifdef _WIN32 -#ifdef ZIP_STATIC -#define ZIP_EXTERN -#else +#ifndef ZIP_EXTERN +#ifndef ZIP_STATIC #define ZIP_EXTERN __declspec(dllexport) +#else +#define ZIP_EXTERN +#endif #endif @@ -56,5 +60,7 @@ #else +#ifndef __cplusplus typedef char bool; -#define true 1 -#define false 0 +#define true 1 +#define false 0 +#endif #endif @@ -78,7 +84,10 @@ typedef char bool; #ifdef _WIN32 +#if defined(HAVE__CHMOD) +#define chmod _chmod +#endif #if defined(HAVE__CLOSE) -#define close _close +#define close _close #endif #if defined(HAVE__DUP) -#define dup _dup +#define dup _dup #endif @@ -86,6 +95,6 @@ typedef char bool; #if defined(HAVE__FDOPEN) -#define fdopen _fdopen +#define fdopen _fdopen #endif #if !defined(HAVE_FILENO) && defined(HAVE__FILENO) -#define fileno _fileno +#define fileno _fileno #endif @@ -93,6 +102,6 @@ typedef char bool; #if defined(HAVE__OPEN) -#define open(a, b, c) _open((a), (b)) +#define open(a, b, c) _open((a), (b)) #endif #if defined(HAVE__SNPRINTF) -#define snprintf _snprintf +#define snprintf _snprintf #endif @@ -101,3 +110,3 @@ typedef char bool; #undef strdup -#define strdup _strdup +#define strdup _strdup #endif @@ -105,9 +114,15 @@ typedef char bool; #if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE) -#define _setmode setmode +#define _setmode setmode #endif #if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64) -#define strtoll _strtoi64 +#define strtoll _strtoi64 #endif #if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64) -#define strtoull _strtoui64 +#define strtoull _strtoui64 +#endif +#if defined(HAVE__UMASK) +#define umask _umask +#endif +#if defined(HAVE__UNLINK) +#define unlink _unlink #endif @@ -116,3 +131,3 @@ typedef char bool; #ifndef HAVE_FSEEKO -#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) +#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) #endif @@ -120,3 +135,3 @@ typedef char bool; #ifndef HAVE_FTELLO -#define ftello(s) ((long)ftell((s))) +#define ftello(s) ((long)ftell((s))) #endif @@ -130,5 +145,5 @@ int _zip_mkstemp(char *); #if defined(HAVE__STRICMP) -#define strcasecmp _stricmp +#define strcasecmp _stricmp #elif defined(HAVE_STRICMP) -#define strcasecmp stricmp +#define strcasecmp stricmp #endif @@ -187,3 +202,3 @@ int _zip_mkstemp(char *); #ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) #endif diff --git a/src/Common/libzip/config.h b/src/Common/libzip/config.h index 8c6c46a0..d6134b48 100644 --- a/src/Common/libzip/config.h +++ b/src/Common/libzip/config.h @@ -7,2 +7,3 @@ /* #undef HAVE___PROGNAME */ +#define HAVE__CHMOD #define HAVE__CLOSE @@ -18,2 +19,8 @@ #define HAVE__STRTOUI64 +#define HAVE__UMASK +#define HAVE__UNLINK +/* #undef HAVE_CLONEFILE */ +/* #undef HAVE_COMMONCRYPTO */ +/* #undef HAVE_CRYPTO */ +/* #undef HAVE_FICLONERANGE */ #define HAVE_FILENO @@ -22,3 +29,6 @@ /* #undef HAVE_GETPROGNAME */ +/* #undef HAVE_GNUTLS */ +/* #undef HAVE_LIBBZ2 */ #define HAVE_OPEN +/* #undef HAVE_OPENSSL */ /* #undef HAVE_MKSTEMP */ @@ -48,2 +58,6 @@ #define UINT64_T_LIBZIP 8 +#define SHORT_LIBZIP 2 +#define INT_LIBZIP 4 +#define LONG_LIBZIP 4 +#define LONG_LONG_LIBZIP 8 #define SIZEOF_OFF_T 4 @@ -56,2 +70,3 @@ /* #undef HAVE_DIRENT_H */ +/* #undef HAVE_FTS_H */ /* #undef HAVE_NDIR_H */ @@ -60,5 +75,6 @@ /* #undef WORDS_BIGENDIAN */ +#define HAVE_SHARED /* END DEFINES */ #define PACKAGE "libzip" -#define VERSION "1.2.0" +#define VERSION "1.5.0a" diff --git a/src/Common/libzip/mkstemp.c b/src/Common/libzip/mkstemp.c index 2ccd3a48..01a531fc 100644 --- a/src/Common/libzip/mkstemp.c +++ b/src/Common/libzip/mkstemp.c @@ -33,4 +33,4 @@ -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> @@ -42,2 +42,5 @@ #include <io.h> +#include <process.h> +#else +#include <unistd.h> #endif @@ -52,97 +55,97 @@ int -_zip_mkstemp(char *path) -{ +_zip_mkstemp(char *path) { #ifdef _WIN32 - int ret; - ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE); - if (ret == -1) { - return 0; - } else { - return ret; - } + int ret; + ret = _creat(_mktemp(path), _S_IREAD | _S_IWRITE); + if (ret == -1) { + return 0; + } + else { + return ret; + } #else - int fd; - char *start, *trv; - struct stat sbuf; - pid_t pid; - - /* To guarantee multiple calls generate unique names even if - the file is not created. 676 different possibilities with 7 - or more X's, 26 with 6 or less. */ - static char xtra[2] = "aa"; - int xcnt = 0; - - pid = getpid(); - - /* Move to end of path and count trailing X's. */ - for (trv = path; *trv; ++trv) - if (*trv == 'X') - xcnt++; - else - xcnt = 0; - - /* Use at least one from xtra. Use 2 if more than 6 X's. */ - if (*(trv - 1) == 'X') - *--trv = xtra[0]; - if (xcnt > 6 && *(trv - 1) == 'X') - *--trv = xtra[1]; - - /* Set remaining X's to pid digits with 0's to the left. */ - while (*--trv == 'X') { - *trv = (pid % 10) + '0'; - pid /= 10; + int fd; + char *start, *trv; + struct stat sbuf; + pid_t pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + static char xtra[2] = "aa"; + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + *trv = '/'; + break; } - - /* update xtra for next call. */ - if (xtra[0] != 'z') - xtra[0]++; - else { - xtra[0] = 'a'; - if (xtra[1] != 'z') - xtra[1]++; + } + + for (;;) { + if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR | O_BINARY, 0600)) >= 0) + return (fd); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; else - xtra[1] = 'a'; - } - - /* - * check the target directory; if you have six X's and it - * doesn't exist this runs for a *very* long time. - */ - for (start = trv + 1;; --trv) { - if (trv <= path) - break; - if (*trv == '/') { - *trv = '\0'; - if (stat(path, &sbuf)) - return (0); - if (!S_ISDIR(sbuf.st_mode)) { - errno = ENOTDIR; - return (0); - } - *trv = '/'; - break; - } - } - - for (;;) { - if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0) - return (fd); - if (errno != EEXIST) - return (0); - - /* tricky little algorithm for backward compatibility */ - for (trv = start;;) { - if (!*trv) - return (0); - if (*trv == 'z') - *trv++ = 'a'; - else { - if (isdigit((unsigned char)*trv)) - *trv = 'a'; - else - ++*trv; - break; - } - } + ++*trv; + break; + } } + } /*NOTREACHED*/ diff --git a/src/Common/libzip/zip.h b/src/Common/libzip/zip.h index abdaf07a..2d83a998 100644 --- a/src/Common/libzip/zip.h +++ b/src/Common/libzip/zip.h @@ -5,3 +5,3 @@ zip.h -- exported declarations. - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -37,16 +37,2 @@ -#ifndef ZIP_EXTERN -# ifndef ZIP_STATIC -# ifdef _WIN32 -# define ZIP_EXTERN __declspec(dllimport) -# elif defined(__GNUC__) && __GNUC__ >= 4 -# define ZIP_EXTERN __attribute__ ((visibility ("default"))) -# else -# define ZIP_EXTERN -# endif -# else -# define ZIP_EXTERN -# endif -#endif - #ifdef __cplusplus @@ -60,4 +46,18 @@ extern "C" { -#include <sys/types.h> +#ifndef ZIP_EXTERN +#ifndef ZIP_STATIC +#ifdef _WIN32 +#define ZIP_EXTERN __declspec(dllimport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ZIP_EXTERN __attribute__((visibility("default"))) +#else +#define ZIP_EXTERN +#endif +#else +#define ZIP_EXTERN +#endif +#endif + #include <stdio.h> +#include <sys/types.h> #include <time.h> @@ -66,7 +66,7 @@ extern "C" { -#define ZIP_CREATE 1 -#define ZIP_EXCL 2 -#define ZIP_CHECKCONS 4 -#define ZIP_TRUNCATE 8 -#define ZIP_RDONLY 16 +#define ZIP_CREATE 1 +#define ZIP_EXCL 2 +#define ZIP_CHECKCONS 4 +#define ZIP_TRUNCATE 8 +#define ZIP_RDONLY 16 @@ -75,17 +75,17 @@ extern "C" { -#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ -#define ZIP_FL_NODIR 2u /* ignore directory component */ -#define ZIP_FL_COMPRESSED 4u /* read compressed data */ -#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ -#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ -#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ -#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ -#define ZIP_FL_ENC_RAW 64u /* get unmodified string */ -#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ -#define ZIP_FL_LOCAL 256u /* in local header */ -#define ZIP_FL_CENTRAL 512u /* in central directory */ +#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ +#define ZIP_FL_NODIR 2u /* ignore directory component */ +#define ZIP_FL_COMPRESSED 4u /* read compressed data */ +#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ +#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ +#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ +#define ZIP_FL_ENC_RAW 64u /* get unmodified string */ +#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ +#define ZIP_FL_LOCAL 256u /* in local header */ +#define ZIP_FL_CENTRAL 512u /* in central directory */ /* 1024u reserved for internal use */ -#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ -#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ -#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ +#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ +#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ +#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ @@ -93,3 +93,3 @@ extern "C" { -#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ +#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ @@ -98,4 +98,4 @@ extern "C" { -#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX -#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX +#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX +#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX @@ -104,33 +104,34 @@ extern "C" { -#define ZIP_ER_OK 0 /* N No error */ -#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ -#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ -#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ -#define ZIP_ER_SEEK 4 /* S Seek error */ -#define ZIP_ER_READ 5 /* S Read error */ -#define ZIP_ER_WRITE 6 /* S Write error */ -#define ZIP_ER_CRC 7 /* N CRC error */ -#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ -#define ZIP_ER_NOENT 9 /* N No such file */ -#define ZIP_ER_EXISTS 10 /* N File already exists */ -#define ZIP_ER_OPEN 11 /* S Can't open file */ -#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ -#define ZIP_ER_ZLIB 13 /* Z Zlib error */ -#define ZIP_ER_MEMORY 14 /* N Malloc failure */ -#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ -#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ -#define ZIP_ER_EOF 17 /* N Premature end of file */ -#define ZIP_ER_INVAL 18 /* N Invalid argument */ -#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ -#define ZIP_ER_INTERNAL 20 /* N Internal error */ -#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ -#define ZIP_ER_REMOVE 22 /* S Can't remove file */ -#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ -#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ -#define ZIP_ER_RDONLY 25 /* N Read-only archive */ -#define ZIP_ER_NOPASSWD 26 /* N No password provided */ -#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */ -#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */ -#define ZIP_ER_INUSE 29 /* N Resource still in use */ -#define ZIP_ER_TELL 30 /* S Tell error */ +#define ZIP_ER_OK 0 /* N No error */ +#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */ +#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */ +#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */ +#define ZIP_ER_SEEK 4 /* S Seek error */ +#define ZIP_ER_READ 5 /* S Read error */ +#define ZIP_ER_WRITE 6 /* S Write error */ +#define ZIP_ER_CRC 7 /* N CRC error */ +#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */ +#define ZIP_ER_NOENT 9 /* N No such file */ +#define ZIP_ER_EXISTS 10 /* N File already exists */ +#define ZIP_ER_OPEN 11 /* S Can't open file */ +#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */ +#define ZIP_ER_ZLIB 13 /* Z Zlib error */ +#define ZIP_ER_MEMORY 14 /* N Malloc failure */ +#define ZIP_ER_CHANGED 15 /* N Entry has been changed */ +#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */ +#define ZIP_ER_EOF 17 /* N Premature end of file */ +#define ZIP_ER_INVAL 18 /* N Invalid argument */ +#define ZIP_ER_NOZIP 19 /* N Not a zip archive */ +#define ZIP_ER_INTERNAL 20 /* N Internal error */ +#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */ +#define ZIP_ER_REMOVE 22 /* S Can't remove file */ +#define ZIP_ER_DELETED 23 /* N Entry has been deleted */ +#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */ +#define ZIP_ER_RDONLY 25 /* N Read-only archive */ +#define ZIP_ER_NOPASSWD 26 /* N No password provided */ +#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */ +#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */ +#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 */ @@ -138,5 +139,5 @@ extern "C" { -#define ZIP_ET_NONE 0 /* sys_err unused */ -#define ZIP_ET_SYS 1 /* sys_err is errno */ -#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ +#define ZIP_ET_NONE 0 /* sys_err unused */ +#define ZIP_ET_SYS 1 /* sys_err is errno */ +#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */ @@ -144,25 +145,25 @@ extern "C" { -#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ -#define ZIP_CM_STORE 0 /* stored (uncompressed) */ -#define ZIP_CM_SHRINK 1 /* shrunk */ -#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ -#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ -#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ -#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ -#define ZIP_CM_IMPLODE 6 /* imploded */ +#define ZIP_CM_DEFAULT -1 /* better of deflate or store */ +#define ZIP_CM_STORE 0 /* stored (uncompressed) */ +#define ZIP_CM_SHRINK 1 /* shrunk */ +#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */ +#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */ +#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */ +#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */ +#define ZIP_CM_IMPLODE 6 /* imploded */ /* 7 - Reserved for Tokenizing compression algorithm */ -#define ZIP_CM_DEFLATE 8 /* deflated */ -#define ZIP_CM_DEFLATE64 9 /* deflate64 */ -#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ +#define ZIP_CM_DEFLATE 8 /* deflated */ +#define ZIP_CM_DEFLATE64 9 /* deflate64 */ +#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */ /* 11 - Reserved by PKWARE */ -#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ +#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */ /* 13 - Reserved by PKWARE */ -#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ +#define ZIP_CM_LZMA 14 /* LZMA (EFS) */ /* 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_XZ 95 /* XZ compressed data */ -#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ -#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ -#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ +#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */ +#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */ +#define ZIP_CM_XZ 95 /* XZ compressed data */ +#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */ +#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */ +#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */ @@ -170,42 +171,42 @@ extern "C" { -#define ZIP_EM_NONE 0 /* not encrypted */ -#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ -#if 0 /* Strong Encryption Header not parsed yet */ -#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ -#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ -#define ZIP_EM_3DES_168 0x6603 -#define ZIP_EM_3DES_112 0x6609 -#define ZIP_EM_PKZIP_AES_128 0x660e -#define ZIP_EM_PKZIP_AES_192 0x660f -#define ZIP_EM_PKZIP_AES_256 0x6610 -#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ -#define ZIP_EM_RC4 0x6801 +#define ZIP_EM_NONE 0 /* not encrypted */ +#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */ +#if 0 /* Strong Encryption Header not parsed yet */ +#define ZIP_EM_DES 0x6601 /* strong encryption: DES */ +#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */ +#define ZIP_EM_3DES_168 0x6603 +#define ZIP_EM_3DES_112 0x6609 +#define ZIP_EM_PKZIP_AES_128 0x660e +#define ZIP_EM_PKZIP_AES_192 0x660f +#define ZIP_EM_PKZIP_AES_256 0x6610 +#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */ +#define ZIP_EM_RC4 0x6801 #endif -#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */ -#define ZIP_EM_AES_192 0x0102 -#define ZIP_EM_AES_256 0x0103 -#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ - -#define ZIP_OPSYS_DOS 0x00u -#define ZIP_OPSYS_AMIGA 0x01u -#define ZIP_OPSYS_OPENVMS 0x02u -#define ZIP_OPSYS_UNIX 0x03u -#define ZIP_OPSYS_VM_CMS 0x04u -#define ZIP_OPSYS_ATARI_ST 0x05u -#define ZIP_OPSYS_OS_2 0x06u -#define ZIP_OPSYS_MACINTOSH 0x07u -#define ZIP_OPSYS_Z_SYSTEM 0x08u -#define ZIP_OPSYS_CPM 0x09u -#define ZIP_OPSYS_WINDOWS_NTFS 0x0au -#define ZIP_OPSYS_MVS 0x0bu -#define ZIP_OPSYS_VSE 0x0cu -#define ZIP_OPSYS_ACORN_RISC 0x0du -#define ZIP_OPSYS_VFAT 0x0eu -#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu -#define ZIP_OPSYS_BEOS 0x10u -#define ZIP_OPSYS_TANDEM 0x11u -#define ZIP_OPSYS_OS_400 0x12u -#define ZIP_OPSYS_OS_X 0x13u - -#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX +#define ZIP_EM_AES_128 0x0101 /* Winzip AES encryption */ +#define ZIP_EM_AES_192 0x0102 +#define ZIP_EM_AES_256 0x0103 +#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */ + +#define ZIP_OPSYS_DOS 0x00u +#define ZIP_OPSYS_AMIGA 0x01u +#define ZIP_OPSYS_OPENVMS 0x02u +#define ZIP_OPSYS_UNIX 0x03u +#define ZIP_OPSYS_VM_CMS 0x04u +#define ZIP_OPSYS_ATARI_ST 0x05u +#define ZIP_OPSYS_OS_2 0x06u +#define ZIP_OPSYS_MACINTOSH 0x07u +#define ZIP_OPSYS_Z_SYSTEM 0x08u +#define ZIP_OPSYS_CPM 0x09u +#define ZIP_OPSYS_WINDOWS_NTFS 0x0au +#define ZIP_OPSYS_MVS 0x0bu +#define ZIP_OPSYS_VSE 0x0cu +#define ZIP_OPSYS_ACORN_RISC 0x0du +#define ZIP_OPSYS_VFAT 0x0eu +#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu +#define ZIP_OPSYS_BEOS 0x10u +#define ZIP_OPSYS_TANDEM 0x11u +#define ZIP_OPSYS_OS_400 0x12u +#define ZIP_OPSYS_OS_X 0x13u + +#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX @@ -213,18 +214,20 @@ extern "C" { enum zip_source_cmd { - ZIP_SOURCE_OPEN, /* prepare for reading */ - ZIP_SOURCE_READ, /* read data */ - ZIP_SOURCE_CLOSE, /* reading is done */ - ZIP_SOURCE_STAT, /* get meta information */ - ZIP_SOURCE_ERROR, /* get error information */ - ZIP_SOURCE_FREE, /* cleanup and free resources */ - ZIP_SOURCE_SEEK, /* set position for reading */ - ZIP_SOURCE_TELL, /* get read position */ - ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ - ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ - ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ - ZIP_SOURCE_WRITE, /* write data */ - ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ - ZIP_SOURCE_TELL_WRITE, /* get write position */ - ZIP_SOURCE_SUPPORTS, /* check whether source supports command */ - ZIP_SOURCE_REMOVE /* remove file */ + ZIP_SOURCE_OPEN, /* prepare for reading */ + ZIP_SOURCE_READ, /* read data */ + ZIP_SOURCE_CLOSE, /* reading is done */ + ZIP_SOURCE_STAT, /* get meta information */ + ZIP_SOURCE_ERROR, /* get error information */ + ZIP_SOURCE_FREE, /* cleanup and free resources */ + ZIP_SOURCE_SEEK, /* set position for reading */ + ZIP_SOURCE_TELL, /* get read position */ + ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */ + ZIP_SOURCE_COMMIT_WRITE, /* writing is done */ + ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */ + ZIP_SOURCE_WRITE, /* write data */ + ZIP_SOURCE_SEEK_WRITE, /* set position for writing */ + ZIP_SOURCE_TELL_WRITE, /* get write position */ + 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 */ }; @@ -232,3 +235,5 @@ typedef enum zip_source_cmd zip_source_cmd_t; -#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (1<<(cmd)) +#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd)) + +// clang-format off @@ -255,2 +260,4 @@ typedef enum zip_source_cmd zip_source_cmd_t; +// clang-format on + /* for use by sources */ @@ -268,28 +275,33 @@ typedef struct zip_source_args_seek zip_source_args_seek_t; struct zip_error { - int zip_err; /* libzip error code (ZIP_ER_*) */ - int sys_err; /* copy of errno (E*) or zlib error code */ - char *str; /* string representation or NULL */ + int zip_err; /* libzip error code (ZIP_ER_*) */ + int sys_err; /* copy of errno (E*) or zlib error code */ + char *str; /* string representation or NULL */ }; -#define ZIP_STAT_NAME 0x0001u -#define ZIP_STAT_INDEX 0x0002u -#define ZIP_STAT_SIZE 0x0004u -#define ZIP_STAT_COMP_SIZE 0x0008u -#define ZIP_STAT_MTIME 0x0010u -#define ZIP_STAT_CRC 0x0020u -#define ZIP_STAT_COMP_METHOD 0x0040u -#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u -#define ZIP_STAT_FLAGS 0x0100u +#define ZIP_STAT_NAME 0x0001u +#define ZIP_STAT_INDEX 0x0002u +#define ZIP_STAT_SIZE 0x0004u +#define ZIP_STAT_COMP_SIZE 0x0008u +#define ZIP_STAT_MTIME 0x0010u +#define ZIP_STAT_CRC 0x0020u +#define ZIP_STAT_COMP_METHOD 0x0040u +#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u +#define ZIP_STAT_FLAGS 0x0100u struct zip_stat { - zip_uint64_t valid; /* which fields have valid values */ - const char *name; /* name of the file */ - zip_uint64_t index; /* index within archive */ - zip_uint64_t size; /* size of file (uncompressed) */ - zip_uint64_t comp_size; /* size of file (compressed) */ - time_t mtime; /* modification time */ - zip_uint32_t crc; /* crc of file data */ - zip_uint16_t comp_method; /* compression method used */ - zip_uint16_t encryption_method; /* encryption method used */ - zip_uint32_t flags; /* reserved for future use */ + zip_uint64_t valid; /* which fields have valid values */ + const char *name; /* name of the file */ + zip_uint64_t index; /* index within archive */ + zip_uint64_t size; /* size of file (uncompressed) */ + zip_uint64_t comp_size; /* size of file (compressed) */ + time_t mtime; /* modification time */ + zip_uint32_t crc; /* crc of file data */ + zip_uint16_t comp_method; /* compression method used */ + zip_uint16_t encryption_method; /* encryption method used */ + zip_uint32_t flags; /* reserved for future use */ +}; + +struct zip_buffer_fragment { + zip_uint8_t *data; + zip_uint64_t length; }; @@ -305,2 +317,3 @@ typedef struct zip_source zip_source_t; typedef struct zip_stat zip_stat_t; +typedef struct zip_buffer_fragment zip_buffer_fragment_t; @@ -309,17 +322,19 @@ 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_t)(double); - +typedef void (*zip_progress_callback)(zip_t *, double, void *); #ifndef ZIP_DISABLE_DEPRECATED -ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */ -ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */ +typedef void (*zip_progress_callback_t)(double); +ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t); /* use zip_register_progress_callback_with_state */ + +ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */ +ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */ ZIP_EXTERN const char *zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */ -ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */ -ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */ -ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */ -ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */ -ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */ -ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */ -ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); -ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */ +ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */ +ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */ +ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */ +ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */ +ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */ +ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */ +ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */ +ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */ #endif @@ -375,2 +390,3 @@ ZIP_EXTERN const char *zip_get_name(zip_t *, zip_uint64_t, zip_flags_t); ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t); +ZIP_EXTERN const char *zip_libzip_version(void); ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t); @@ -378,3 +394,3 @@ 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 void zip_register_progress_callback(zip_t *, zip_progress_callback_t); +ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *, double, zip_progress_callback, void (*)(void *), void *); ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t); @@ -384,4 +400,7 @@ ZIP_EXTERN int zip_set_file_compression(zip_t *, zip_uint64_t, zip_int32_t, zip_ ZIP_EXTERN int zip_source_begin_write(zip_source_t *); +ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *, zip_uint64_t); ZIP_EXTERN zip_source_t *zip_source_buffer(zip_t *, const void *, zip_uint64_t, int); ZIP_EXTERN zip_source_t *zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *); +ZIP_EXTERN zip_source_t *zip_source_buffer_fragment(zip_t *, const zip_buffer_fragment_t *, zip_uint64_t, int); +ZIP_EXTERN zip_source_t *zip_source_buffer_fragment_create(const zip_buffer_fragment_t *, zip_uint64_t, int, zip_error_t *); ZIP_EXTERN int zip_source_close(zip_source_t *); diff --git a/src/Common/libzip/zip_add.c b/src/Common/libzip/zip_add.c index d1be133b..69966d32 100644 --- a/src/Common/libzip/zip_add.c +++ b/src/Common/libzip/zip_add.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,5 +40,5 @@ NOTE: Return type is signed so we can return -1 on error. - The index can not be larger than ZIP_INT64_MAX since the size - of the central directory cannot be larger than - ZIP_UINT64_MAX, and each entry is larger than 2 bytes. + The index can not be larger than ZIP_INT64_MAX since the size + of the central directory cannot be larger than + ZIP_UINT64_MAX, and each entry is larger than 2 bytes. */ @@ -46,4 +46,3 @@ ZIP_EXTERN zip_int64_t -zip_add(zip_t *za, const char *name, zip_source_t *source) -{ +zip_add(zip_t *za, const char *name, zip_source_t *source) { return zip_file_add(za, name, source, 0); diff --git a/src/Common/libzip/zip_add_dir.c b/src/Common/libzip/zip_add_dir.c index 14bdeda1..a0026a70 100644 --- a/src/Common/libzip/zip_add_dir.c +++ b/src/Common/libzip/zip_add_dir.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ ZIP_EXTERN zip_int64_t -zip_add_dir(zip_t *za, const char *name) -{ +zip_add_dir(zip_t *za, const char *name) { return zip_dir_add(za, name, 0); diff --git a/src/Common/libzip/zip_add_entry.c b/src/Common/libzip/zip_add_entry.c index f6212f15..f1de4459 100644 --- a/src/Common/libzip/zip_add_entry.c +++ b/src/Common/libzip/zip_add_entry.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -42,7 +42,6 @@ zip_int64_t -_zip_add_entry(zip_t *za) -{ +_zip_add_entry(zip_t *za) { zip_uint64_t idx; - if (za->nentry+1 >= za->nentry_alloc) { + if (za->nentry + 1 >= za->nentry_alloc) { zip_entry_t *rentries; @@ -77,3 +76,3 @@ _zip_add_entry(zip_t *za) - _zip_entry_init(za->entry+idx); + _zip_entry_init(za->entry + idx); diff --git a/src/Common/libzip/zip_algorithm_deflate.c b/src/Common/libzip/zip_algorithm_deflate.c new file mode 100644 index 00000000..2a1c904e --- /dev/null +++ b/src/Common/libzip/zip_algorithm_deflate.c @@ -0,0 +1,247 @@ +/* + zip_algorithm_deflate.c -- deflate (de)compression routines + Copyright (C) 2017 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" + +#include <limits.h> +#include <stdlib.h> +#include <zlib.h> + +struct ctx { + zip_error_t *error; + bool compress; + int compression_flags; + bool end_of_input; + z_stream zstr; +}; + + +static void * +allocate(bool compress, int compression_flags, zip_error_t *error) { + struct ctx *ctx; + + if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { + return NULL; + } + + ctx->error = error; + ctx->compress = compress; + ctx->compression_flags = compression_flags; + if (ctx->compression_flags < 1 || ctx->compression_flags > 9) { + ctx->compression_flags = Z_BEST_COMPRESSION; + } + ctx->end_of_input = false; + + ctx->zstr.zalloc = Z_NULL; + ctx->zstr.zfree = Z_NULL; + ctx->zstr.opaque = NULL; + + return ctx; +} + + +static void * +compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { + return allocate(true, compression_flags, error); +} + + +static void * +decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) { + return allocate(false, compression_flags, error); +} + + +static void +deallocate(void *ud) { + struct ctx *ctx = (struct ctx *)ud; + + free(ctx); +} + + +static int +compression_flags(void *ud) { + struct ctx *ctx = (struct ctx *)ud; + + if (!ctx->compress) { + return 0; + } + + if (ctx->compression_flags < 3) { + return 2; + } + else if (ctx->compression_flags > 7) { + return 1; + } + return 0; +} + + +static bool +start(void *ud) { + struct ctx *ctx = (struct ctx *)ud; + int ret; + + ctx->zstr.avail_in = 0; + ctx->zstr.next_in = NULL; + ctx->zstr.avail_out = 0; + ctx->zstr.next_out = NULL; + + if (ctx->compress) { + /* negative value to tell zlib not to write a header */ + ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + } + else { + ret = inflateInit2(&ctx->zstr, -MAX_WBITS); + } + + if (ret != Z_OK) { + zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); + return false; + } + + + return true; +} + + +static bool +end(void *ud) { + struct ctx *ctx = (struct ctx *)ud; + int err; + + if (ctx->compress) { + err = deflateEnd(&ctx->zstr); + } + else { + err = inflateEnd(&ctx->zstr); + } + + if (err != Z_OK) { + zip_error_set(ctx->error, ZIP_ER_ZLIB, err); + return false; + } + + return true; +} + + +static bool +input(void *ud, zip_uint8_t *data, zip_uint64_t length) { + struct ctx *ctx = (struct ctx *)ud; + + if (length > UINT_MAX || ctx->zstr.avail_in > 0) { + zip_error_set(ctx->error, ZIP_ER_INVAL, 0); + return false; + } + + ctx->zstr.avail_in = (uInt)length; + ctx->zstr.next_in = (Bytef *)data; + + return true; +} + + +static void +end_of_input(void *ud) { + struct ctx *ctx = (struct ctx *)ud; + + ctx->end_of_input = true; +} + + +static zip_compression_status_t +process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { + struct ctx *ctx = (struct ctx *)ud; + + int ret; + + ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length); + ctx->zstr.next_out = (Bytef *)data; + + if (ctx->compress) { + ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0); + } + else { + ret = inflate(&ctx->zstr, Z_SYNC_FLUSH); + } + + *length = *length - ctx->zstr.avail_out; + + switch (ret) { + case Z_OK: + return ZIP_COMPRESSION_OK; + + case Z_STREAM_END: + return ZIP_COMPRESSION_END; + + case Z_BUF_ERROR: + if (ctx->zstr.avail_in == 0) { + return ZIP_COMPRESSION_NEED_DATA; + } + + /* fallthrough */ + + default: + zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); + return ZIP_COMPRESSION_ERROR; + } +} + +// clang-format off + +zip_compression_algorithm_t zip_algorithm_deflate_compress = { + compress_allocate, + deallocate, + compression_flags, + start, + end, + input, + end_of_input, + process +}; + + +zip_compression_algorithm_t zip_algorithm_deflate_decompress = { + decompress_allocate, + deallocate, + compression_flags, + start, + end, + input, + end_of_input, + process +}; + +// clang-format on diff --git a/src/Common/libzip/zip_buffer.c b/src/Common/libzip/zip_buffer.c index 7addc4b6..96010b23 100644 --- a/src/Common/libzip/zip_buffer.c +++ b/src/Common/libzip/zip_buffer.c @@ -39,4 +39,3 @@ zip_uint8_t * -_zip_buffer_data(zip_buffer_t *buffer) -{ +_zip_buffer_data(zip_buffer_t *buffer) { return buffer->data; @@ -46,6 +45,5 @@ _zip_buffer_data(zip_buffer_t *buffer) void -_zip_buffer_free(zip_buffer_t *buffer) -{ +_zip_buffer_free(zip_buffer_t *buffer) { if (buffer == NULL) { - return; + return; } @@ -53,3 +51,3 @@ _zip_buffer_free(zip_buffer_t *buffer) if (buffer->free_data) { - free(buffer->data); + free(buffer->data); } @@ -61,4 +59,3 @@ _zip_buffer_free(zip_buffer_t *buffer) bool -_zip_buffer_eof(zip_buffer_t *buffer) -{ +_zip_buffer_eof(zip_buffer_t *buffer) { return buffer->ok && buffer->offset == buffer->size; @@ -68,4 +65,3 @@ _zip_buffer_eof(zip_buffer_t *buffer) zip_uint8_t * -_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) -{ +_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) { zip_uint8_t *data; @@ -83,4 +79,3 @@ _zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) zip_uint16_t -_zip_buffer_get_16(zip_buffer_t *buffer) -{ +_zip_buffer_get_16(zip_buffer_t *buffer) { zip_uint8_t *data = _zip_buffer_get(buffer, 2); @@ -88,3 +83,3 @@ _zip_buffer_get_16(zip_buffer_t *buffer) if (data == NULL) { - return 0; + return 0; } @@ -96,4 +91,3 @@ _zip_buffer_get_16(zip_buffer_t *buffer) zip_uint32_t -_zip_buffer_get_32(zip_buffer_t *buffer) -{ +_zip_buffer_get_32(zip_buffer_t *buffer) { zip_uint8_t *data = _zip_buffer_get(buffer, 4); @@ -101,3 +95,3 @@ _zip_buffer_get_32(zip_buffer_t *buffer) if (data == NULL) { - return 0; + return 0; } @@ -109,4 +103,3 @@ _zip_buffer_get_32(zip_buffer_t *buffer) zip_uint64_t -_zip_buffer_get_64(zip_buffer_t *buffer) -{ +_zip_buffer_get_64(zip_buffer_t *buffer) { zip_uint8_t *data = _zip_buffer_get(buffer, 8); @@ -114,3 +107,3 @@ _zip_buffer_get_64(zip_buffer_t *buffer) if (data == NULL) { - return 0; + return 0; } @@ -121,6 +114,4 @@ _zip_buffer_get_64(zip_buffer_t *buffer) - zip_uint8_t -_zip_buffer_get_8(zip_buffer_t *buffer) -{ +_zip_buffer_get_8(zip_buffer_t *buffer) { zip_uint8_t *data = _zip_buffer_get(buffer, 1); @@ -128,3 +119,3 @@ _zip_buffer_get_8(zip_buffer_t *buffer) if (data == NULL) { - return 0; + return 0; } @@ -136,4 +127,3 @@ _zip_buffer_get_8(zip_buffer_t *buffer) zip_uint64_t -_zip_buffer_left(zip_buffer_t *buffer) -{ +_zip_buffer_left(zip_buffer_t *buffer) { return buffer->ok ? buffer->size - buffer->offset : 0; @@ -143,4 +133,3 @@ _zip_buffer_left(zip_buffer_t *buffer) zip_uint64_t -_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) -{ +_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { if (_zip_buffer_left(buffer) < length) { @@ -156,4 +145,3 @@ _zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) zip_buffer_t * -_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) -{ +_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) { bool free_data = (data == NULL); @@ -162,5 +150,5 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) if (data == NULL) { - if ((data = (zip_uint8_t *)malloc(size)) == NULL) { - return NULL; - } + if ((data = (zip_uint8_t *)malloc(size)) == NULL) { + return NULL; + } } @@ -168,6 +156,6 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) { - if (free_data) { - free(data); - } - return NULL; + if (free_data) { + free(data); + } + return NULL; } @@ -185,4 +173,3 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) zip_buffer_t * -_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) -{ +_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) { zip_buffer_t *buffer; @@ -190,4 +177,4 @@ _zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *b if ((buffer = _zip_buffer_new(buf, size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; } @@ -195,4 +182,4 @@ _zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *b if (_zip_read(src, buffer->data, size, error) < 0) { - _zip_buffer_free(buffer); - return NULL; + _zip_buffer_free(buffer); + return NULL; } @@ -204,4 +191,3 @@ _zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *b zip_uint64_t -_zip_buffer_offset(zip_buffer_t *buffer) -{ +_zip_buffer_offset(zip_buffer_t *buffer) { return buffer->ok ? buffer->offset : 0; @@ -211,4 +197,3 @@ _zip_buffer_offset(zip_buffer_t *buffer) bool -_zip_buffer_ok(zip_buffer_t *buffer) -{ +_zip_buffer_ok(zip_buffer_t *buffer) { return buffer->ok; @@ -217,6 +202,4 @@ _zip_buffer_ok(zip_buffer_t *buffer) - zip_uint8_t * -_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) -{ +_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) { zip_uint8_t *data; @@ -224,4 +207,4 @@ _zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) { - buffer->ok = false; - return NULL; + buffer->ok = false; + return NULL; } @@ -233,4 +216,3 @@ _zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) int -_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) -{ +_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) { zip_uint8_t *dst = _zip_buffer_get(buffer, length); @@ -238,3 +220,3 @@ _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) if (dst == NULL) { - return -1; + return -1; } @@ -247,4 +229,3 @@ _zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) int -_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) -{ +_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) { zip_uint8_t *data = _zip_buffer_get(buffer, 2); @@ -252,3 +233,3 @@ _zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) if (data == NULL) { - return -1; + return -1; } @@ -263,4 +244,3 @@ _zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) int -_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) -{ +_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) { zip_uint8_t *data = _zip_buffer_get(buffer, 4); @@ -268,3 +248,3 @@ _zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) if (data == NULL) { - return -1; + return -1; } @@ -281,4 +261,3 @@ _zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) int -_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) -{ +_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) { zip_uint8_t *data = _zip_buffer_get(buffer, 8); @@ -286,3 +265,3 @@ _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) if (data == NULL) { - return -1; + return -1; } @@ -303,4 +282,3 @@ _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) int -_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) -{ +_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) { zip_uint8_t *data = _zip_buffer_get(buffer, 1); @@ -308,3 +286,3 @@ _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) if (data == NULL) { - return -1; + return -1; } @@ -318,7 +296,6 @@ _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) int -_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) -{ +_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) { if (offset > buffer->size) { - buffer->ok = false; - return -1; + buffer->ok = false; + return -1; } @@ -337,4 +314,4 @@ _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) { if (offset < buffer->offset) { - buffer->ok = false; - return -1; + buffer->ok = false; + return -1; } @@ -344,4 +321,3 @@ _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) { zip_uint64_t -_zip_buffer_size(zip_buffer_t *buffer) -{ +_zip_buffer_size(zip_buffer_t *buffer) { return buffer->size; diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c index 88fa4449..c46e1b34 100644 --- a/src/Common/libzip/zip_close.c +++ b/src/Common/libzip/zip_close.c @@ -2,3 +2,3 @@ zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -45,7 +45,7 @@ #endif -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> #ifdef _WIN32 -#include <io.h> #include <fcntl.h> +#include <io.h> #endif @@ -53,15 +53,10 @@ -/* max deflate size increase: size + ceil(size/16k)*5+6 */ -#define MAX_DEFLATE_SIZE_32 4293656963u - static int add_data(zip_t *, zip_source_t *, zip_dirent_t *); static int copy_data(zip_t *, zip_uint64_t); -static int copy_source(zip_t *, zip_source_t *); +static int copy_source(zip_t *, zip_source_t *, zip_int64_t); static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t); - ZIP_EXTERN int -zip_close(zip_t *za) -{ - zip_uint64_t i, j, survivors; +zip_close(zip_t *za) { + zip_uint64_t i, j, survivors, unchanged_offset; zip_int64_t off; @@ -86,3 +81,3 @@ zip_close(zip_t *za) return 0; - } + } @@ -94,20 +89,25 @@ zip_close(zip_t *za) if (survivors > za->nentry) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } - - if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL) + + if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL) return -1; + unchanged_offset = ZIP_UINT64_MAX; /* create list of files with index into original archive */ - for (i=j=0; i<za->nentry; i++) { - if (za->entry[i].deleted) + for (i = j = 0; i < za->nentry; i++) { + if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { + unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset); + } + if (za->entry[i].deleted) { continue; + } + + if (j >= survivors) { + free(filelist); + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } - if (j >= survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - filelist[j].idx = i; @@ -116,15 +116,49 @@ zip_close(zip_t *za) if (j < survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - if (zip_source_begin_write(za->src) < 0) { - _zip_error_set_from_source(&za->error, za->src); free(filelist); + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } - + + if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { + unchanged_offset = 0; + } + else { + if (unchanged_offset == ZIP_UINT64_MAX) { + /* we're keeping all file data, find the end of the last one */ + zip_uint64_t last_index = ZIP_UINT64_MAX; + unchanged_offset = 0; + + for (i = 0; i < za->nentry; i++) { + if (za->entry[i].orig != NULL) { + if (za->entry[i].orig->offset >= unchanged_offset) { + unchanged_offset = za->entry[i].orig->offset; + last_index = i; + } + } + } + if (last_index != ZIP_UINT64_MAX) { + if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) { + free(filelist); + return -1; + } + } + } + if (unchanged_offset > 0) { + if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) { + /* cloning not supported, need to copy everything */ + unchanged_offset = 0; + } + } + } + if (unchanged_offset == 0) { + if (zip_source_begin_write(za->src) < 0) { + _zip_error_set_from_source(&za->error, za->src); + free(filelist); + return -1; + } + } + + _zip_progress_start(za->progress); error = 0; - for (j=0; j<survivors; j++) { + for (j = 0; j < survivors; j++) { int new_data; @@ -133,8 +167,11 @@ zip_close(zip_t *za) - if (za->progress_callback) { - za->progress_callback((double)j/survivors); - } + _zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors); i = filelist[j].idx; - entry = za->entry+i; + entry = za->entry + i; + + if (entry->orig != NULL && entry->orig->offset < unchanged_offset) { + /* already implicitly copied by cloning */ + continue; + } @@ -144,6 +181,6 @@ zip_close(zip_t *za) if (entry->changes == NULL) { - if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - error = 1; - break; + if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + error = 1; + break; } @@ -157,7 +194,7 @@ zip_close(zip_t *za) - if ((off = zip_source_tell_write(za->src)) < 0) { - error = 1; - break; - } - de->offset = (zip_uint64_t)off; + if ((off = zip_source_tell_write(za->src)) < 0) { + error = 1; + break; + } + de->offset = (zip_uint64_t)off; @@ -168,3 +205,3 @@ zip_close(zip_t *za) if (!ZIP_ENTRY_DATA_CHANGED(entry)) { - if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { + if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { error = 1; @@ -193,3 +230,3 @@ zip_close(zip_t *za) } - if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) { + if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) { error = 1; @@ -223,2 +260,4 @@ zip_close(zip_t *za) + _zip_progress_end(za->progress); + if (error) { @@ -228,8 +267,4 @@ zip_close(zip_t *za) - if (za->progress_callback) { - za->progress_callback(1); - } - zip_discard(za); - + return 0; @@ -239,5 +274,4 @@ zip_close(zip_t *za) static int -add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) -{ - zip_int64_t offstart, offdata, offend; +add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) { + zip_int64_t offstart, offdata, offend, data_length; struct zip_stat st; @@ -247,4 +281,5 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) zip_flags_t flags; + zip_int8_t compression_flags; bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt; - + if (zip_source_stat(src, &st) < 0) { @@ -277,11 +312,37 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) - if ((st.valid & ZIP_STAT_SIZE) == 0) + if ((st.valid & ZIP_STAT_SIZE) == 0) { flags |= ZIP_FL_FORCE_ZIP64; + data_length = -1; + } else { de->uncomp_size = st.size; - + /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */ + data_length = (zip_int64_t)st.size; + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { - if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32) - || (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method)))) + zip_uint64_t max_size; + + switch (ZIP_CM_ACTUAL(de->comp_method)) { + case ZIP_CM_BZIP2: + /* computed by looking at increase of 10 random files of size 1MB when + * compressed with bzip2, rounded up: 1.006 */ + max_size = 4269351188u; + break; + + case ZIP_CM_DEFLATE: + /* max deflate size increase: size + ceil(size/16k)*5+6 */ + max_size = 4293656963u; + break; + + case ZIP_CM_STORE: + max_size = 0xffffffffu; + break; + + default: + max_size = 0; + } + + if (st.size > max_size) { flags |= ZIP_FL_FORCE_ZIP64; + } } @@ -292,3 +353,4 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) if ((offstart = zip_source_tell_write(za->src)) < 0) { - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } @@ -297,6 +359,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; - if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0) + if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) { return -1; + } - needs_recompress = !((st.comp_method == de->comp_method) || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method == ZIP_CM_DEFLATE)); + needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method); needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE); @@ -314,3 +377,3 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) zip_encryption_implementation impl; - + if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { @@ -329,13 +392,5 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) } - + if (needs_decompress) { - zip_compression_implementation comp_impl; - - if ((comp_impl = _zip_get_compression_implementation(st.comp_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - zip_source_free(src_final); - return -1; - } - if ((src_tmp = comp_impl(za, src_final, st.comp_method, ZIP_CODEC_DECODE)) == NULL) { - /* error set by comp_impl */ + if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) { zip_source_free(src_final); @@ -359,6 +414,3 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) if (needs_compress) { - zip_compression_implementation comp_impl; - - if ((comp_impl = _zip_get_compression_implementation(de->comp_method, ZIP_CODEC_ENCODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) { zip_source_free(src_final); @@ -366,7 +418,3 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) } - if ((src_tmp = comp_impl(za, src_final, de->comp_method, ZIP_CODEC_ENCODE)) == NULL) { - zip_source_free(src_final); - return -1; - } - + zip_source_free(src_final); @@ -375,3 +423,3 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) - + if (needs_encrypt) { @@ -382,6 +430,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) password = de->password; - } else if (za->default_password) { + } + else if (za->default_password) { password = za->default_password; } - + if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) { @@ -403,8 +452,15 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) if ((offdata = zip_source_tell_write(za->src)) < 0) { - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } - ret = copy_source(za, src_final); - + ret = copy_source(za, src_final, data_length); + if (zip_source_stat(src_final, &st) < 0) { + _zip_error_set_from_source(&za->error, src_final); + ret = -1; + } + + if ((compression_flags = zip_source_get_compression_flags(src_final)) < 0) { + _zip_error_set_from_source(&za->error, src_final); ret = -1; @@ -419,3 +475,4 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) if ((offend = zip_source_tell_write(za->src)) < 0) { - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } @@ -427,3 +484,3 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) - if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) { + if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); @@ -433,6 +490,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) { - if (st.valid & ZIP_STAT_MTIME) - de->last_mod = st.mtime; - else - time(&de->last_mod); + if (st.valid & ZIP_STAT_MTIME) + de->last_mod = st.mtime; + else + time(&de->last_mod); } @@ -442,6 +499,8 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) de->comp_size = (zip_uint64_t)(offend - offdata); + de->bitflags = (zip_uint16_t)((de->bitflags & (zip_uint16_t)~6) | ((zip_uint8_t)compression_flags << 1)); + _zip_dirent_set_version_needed(de, (flags & ZIP_FL_FORCE_ZIP64) != 0); - if ((ret=_zip_dirent_write(za, de, flags)) < 0) + if ((ret = _zip_dirent_write(za, de, flags)) < 0) return -1; - + if (is_zip64 != ret) { @@ -452,3 +511,2 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) - if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) { @@ -463,6 +521,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) static int -copy_data(zip_t *za, zip_uint64_t len) -{ +copy_data(zip_t *za, zip_uint64_t len) { zip_uint8_t buf[BUFSIZE]; size_t n; + double total = (double)len; @@ -477,4 +535,6 @@ copy_data(zip_t *za, zip_uint64_t len) } - + len -= n; + + _zip_progress_update(za->progress, (total - (double)len) / total); } @@ -486,6 +546,5 @@ copy_data(zip_t *za, zip_uint64_t len) static int -copy_source(zip_t *za, zip_source_t *src) -{ +copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { zip_uint8_t buf[BUFSIZE]; - zip_int64_t n; + zip_int64_t n, current; int ret; @@ -498,3 +557,4 @@ copy_source(zip_t *za, zip_source_t *src) ret = 0; - while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) { + current = 0; + while ((n = zip_source_read(src, buf, sizeof(buf))) > 0) { if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { @@ -503,4 +563,8 @@ copy_source(zip_t *za, zip_source_t *src) } + if (n == sizeof(buf) && za->progress && data_length > 0) { + current += n; + _zip_progress_update(za->progress, (double)current / (double)data_length); + } } - + if (n < 0) { @@ -511,3 +575,3 @@ copy_source(zip_t *za, zip_source_t *src) zip_source_close(src); - + return ret; @@ -515,18 +579,16 @@ copy_source(zip_t *za, zip_source_t *src) - static int -write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) -{ +write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { zip_int64_t cd_start, end, size; - + if ((cd_start = zip_source_tell_write(za->src)) < 0) { - return -1; + return -1; } - if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) { + if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { return -1; } - + if ((end = zip_source_tell_write(za->src)) < 0) { - return -1; + return -1; } @@ -538,4 +600,3 @@ write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) int -_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) -{ +_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { int changed; @@ -546,14 +607,18 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) - if (za->comment_changed || za->ch_flags != za->flags) + if (za->comment_changed || za->ch_flags != za->flags) { changed = 1; + } - for (i=0; i<za->nentry; i++) { - if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0)) + for (i = 0; i < za->nentry; i++) { + if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { changed = 1; - if (!za->entry[i].deleted) + } + if (!za->entry[i].deleted) { survivors++; + } } - if (survivorsp) + if (survivorsp) { *survivorsp = survivors; + } diff --git a/src/Common/libzip/zip_delete.c b/src/Common/libzip/zip_delete.c index e1602101..ae8f5a68 100644 --- a/src/Common/libzip/zip_delete.c +++ b/src/Common/libzip/zip_delete.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_delete(zip_t *za, zip_uint64_t idx) -{ +zip_delete(zip_t *za, zip_uint64_t idx) { const char *name; @@ -52,3 +51,3 @@ zip_delete(zip_t *za, zip_uint64_t idx) - if ((name=_zip_get_name(za, idx, 0, &za->error)) == NULL) { + if ((name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { return -1; @@ -69,2 +68 @@ zip_delete(zip_t *za, zip_uint64_t idx) } - diff --git a/src/Common/libzip/zip_dir_add.c b/src/Common/libzip/zip_dir_add.c index f535b21f..236b4396 100644 --- a/src/Common/libzip/zip_dir_add.c +++ b/src/Common/libzip/zip_dir_add.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -43,4 +43,3 @@ ZIP_EXTERN zip_int64_t -zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) -{ +zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) { size_t len; @@ -63,4 +62,4 @@ zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) - if (name[len-1] != '/') { - if ((s=(char *)malloc(len+2)) == NULL) { + if (name[len - 1] != '/') { + if ((s = (char *)malloc(len + 2)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -70,6 +69,6 @@ zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) s[len] = '/'; - s[len+1] = '\0'; + s[len + 1] = '\0'; } - if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + if ((source = zip_source_buffer(za, NULL, 0, 0)) == NULL) { free(s); @@ -77,3 +76,3 @@ zip_dir_add(zip_t *za, const char *name, zip_flags_t flags) } - + idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags); diff --git a/src/Common/libzip/zip_dirent.c b/src/Common/libzip/zip_dirent.c index df38afd9..060e1e95 100644 --- a/src/Common/libzip/zip_dirent.c +++ b/src/Common/libzip/zip_dirent.c @@ -2,3 +2,3 @@ zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -37,4 +37,4 @@ #include <string.h> -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> #include <time.h> @@ -50,4 +50,3 @@ static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) void -_zip_cdir_free(zip_cdir_t *cd) -{ +_zip_cdir_free(zip_cdir_t *cd) { zip_uint64_t i; @@ -57,4 +56,4 @@ _zip_cdir_free(zip_cdir_t *cd) - for (i=0; i<cd->nentry; i++) - _zip_entry_finalize(cd->entry+i); + for (i = 0; i < cd->nentry; i++) + _zip_entry_finalize(cd->entry + i); free(cd->entry); @@ -66,7 +65,6 @@ _zip_cdir_free(zip_cdir_t *cd) zip_cdir_t * -_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) -{ +_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) { zip_cdir_t *cd; - if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) { + if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -91,4 +89,3 @@ _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) bool -_zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) -{ +_zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) { zip_uint64_t i, new_alloc; @@ -102,3 +99,3 @@ _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *err - if (new_alloc < additional_entries || new_alloc > SIZE_MAX/sizeof(*(cd->entry))) { + if (new_alloc < additional_entries || new_alloc > SIZE_MAX / sizeof(*(cd->entry))) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -107,3 +104,3 @@ _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *err - if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry))*(size_t)new_alloc)) == NULL) { + if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry)) * (size_t)new_alloc)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -115,3 +112,3 @@ _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *err for (i = cd->nentry; i < new_alloc; i++) { - _zip_entry_init(cd->entry+i); + _zip_entry_init(cd->entry + i); } @@ -125,4 +122,3 @@ _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *err zip_int64_t -_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) -{ +_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { zip_uint64_t offset, size; @@ -137,4 +133,4 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } @@ -144,6 +140,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor - for (i=0; i<survivors; i++) { - zip_entry_t *entry = za->entry+filelist[i].idx; + for (i = 0; i < survivors; i++) { + zip_entry_t *entry = za->entry + filelist[i].idx; - if ((ret=_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0) + if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0) return -1; @@ -154,4 +150,4 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor if ((off = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } @@ -164,4 +160,4 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } @@ -170,3 +166,3 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor _zip_buffer_put(buffer, EOCD64_MAGIC, 4); - _zip_buffer_put_64(buffer, EOCD64LEN-12); + _zip_buffer_put_64(buffer, EOCD64LEN - 12); _zip_buffer_put_16(buffer, 45); @@ -181,3 +177,3 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor _zip_buffer_put_32(buffer, 0); - _zip_buffer_put_64(buffer, offset+size); + _zip_buffer_put_64(buffer, offset + size); _zip_buffer_put_32(buffer, 1); @@ -197,5 +193,5 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(buffer); + return -1; } @@ -203,3 +199,3 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) { - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); return -1; @@ -220,7 +216,6 @@ _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivor zip_dirent_t * -_zip_dirent_clone(const zip_dirent_t *sde) -{ +_zip_dirent_clone(const zip_dirent_t *sde) { zip_dirent_t *tde; - if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL) + if ((tde = (zip_dirent_t *)malloc(sizeof(*tde))) == NULL) return NULL; @@ -240,4 +235,3 @@ _zip_dirent_clone(const zip_dirent_t *sde) void -_zip_dirent_finalize(zip_dirent_t *zde) -{ +_zip_dirent_finalize(zip_dirent_t *zde) { if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) { @@ -265,4 +259,3 @@ _zip_dirent_finalize(zip_dirent_t *zde) void -_zip_dirent_free(zip_dirent_t *zde) -{ +_zip_dirent_free(zip_dirent_t *zde) { if (zde == NULL) @@ -276,4 +269,3 @@ _zip_dirent_free(zip_dirent_t *zde) void -_zip_dirent_init(zip_dirent_t *de) -{ +_zip_dirent_init(zip_dirent_t *de) { de->changed = 0; @@ -283,4 +275,4 @@ _zip_dirent_init(zip_dirent_t *de) de->crc_valid = true; - de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8); - de->version_needed = 20; /* 2.0 */ + de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8); + de->version_needed = 10; /* 1.0 */ de->bitflags = 0; @@ -298,2 +290,3 @@ _zip_dirent_init(zip_dirent_t *de) de->offset = 0; + de->compression_level = 0; de->encryption_method = ZIP_EM_NONE; @@ -304,6 +297,4 @@ _zip_dirent_init(zip_dirent_t *de) bool -_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) -{ - if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX - || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) +_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) { + if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) return true; @@ -315,7 +306,6 @@ _zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) zip_dirent_t * -_zip_dirent_new(void) -{ +_zip_dirent_new(void) { zip_dirent_t *de; - if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL) + if ((de = (zip_dirent_t *)malloc(sizeof(*de))) == NULL) return NULL; @@ -338,4 +328,3 @@ _zip_dirent_new(void) zip_int64_t -_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) -{ +_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) { zip_uint8_t buf[CDENTRYSIZE]; @@ -350,11 +339,11 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (buffer) { - if (_zip_buffer_left(buffer) < size) { - zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } + if (_zip_buffer_left(buffer) < size) { + zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } } else { - if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) { - return -1; - } + if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) { + return -1; + } } @@ -363,5 +352,5 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zip_error_set(error, ZIP_ER_NOZIP, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; @@ -398,3 +387,4 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zde->offset = 0; - } else { + } + else { comment_len = _zip_buffer_get_16(buffer); @@ -407,7 +397,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; + zip_error_set(error, ZIP_ER_INTERNAL, 0); + if (!from_buffer) { + _zip_buffer_free(buffer); + } + return -1; } @@ -431,16 +421,16 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo - variable_size = (zip_uint32_t)filename_len+(zip_uint32_t)ef_len+(zip_uint32_t)comment_len; + variable_size = (zip_uint32_t)filename_len + (zip_uint32_t)ef_len + (zip_uint32_t)comment_len; if (from_buffer) { - if (_zip_buffer_left(buffer) < variable_size) { - zip_error_set(error, ZIP_ER_INCONS, 0); - return -1; - } + if (_zip_buffer_left(buffer) < variable_size) { + zip_error_set(error, ZIP_ER_INCONS, 0); + return -1; + } } else { - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); - if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) { - return -1; - } + if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) { + return -1; + } } @@ -449,11 +439,11 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zde->filename = _zip_read_string(buffer, src, filename_len, 1, error); - if (!zde->filename) { - if (zip_error_code_zip(error) == ZIP_ER_EOF) { - zip_error_set(error, ZIP_ER_INCONS, 0); - } - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!zde->filename) { + if (zip_error_code_zip(error) == ZIP_ER_EOF) { + zip_error_set(error, ZIP_ER_INCONS, 0); + } + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; - } + } @@ -462,5 +452,5 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zip_error_set(error, ZIP_ER_INCONS, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; @@ -473,13 +463,13 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo - if (ef == NULL) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (ef == NULL) { + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; - } - if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) { + } + if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) { free(ef); - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; @@ -493,8 +483,8 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zde->comment = _zip_read_string(buffer, src, comment_len, 0, error); - if (!zde->comment) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!zde->comment) { + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; - } + } if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { @@ -502,5 +492,5 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zip_error_set(error, ZIP_ER_INCONS, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; @@ -517,19 +507,19 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo zip_uint16_t got_len; - zip_buffer_t *ef_buffer; + zip_buffer_t *ef_buffer; const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error); /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */ - if (ef == NULL) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } + if (ef == NULL) { + if (!from_buffer) { + _zip_buffer_free(buffer); + } return -1; - } + } - if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } + if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + if (!from_buffer) { + _zip_buffer_free(buffer); + } + return -1; + } @@ -540,3 +530,3 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo include BOTH original and compressed file size fields. */ - (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */ + (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */ } @@ -551,11 +541,11 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo - if (!_zip_buffer_eof(ef_buffer)) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(ef_buffer); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; - } - _zip_buffer_free(ef_buffer); + if (!_zip_buffer_eof(ef_buffer)) { + zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_buffer_free(ef_buffer); + if (!from_buffer) { + _zip_buffer_free(buffer); + } + return -1; + } + _zip_buffer_free(ef_buffer); } @@ -563,10 +553,10 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (!from_buffer) { - _zip_buffer_free(buffer); - } - return -1; + zip_error_set(error, ZIP_ER_INTERNAL, 0); + if (!from_buffer) { + _zip_buffer_free(buffer); + } + return -1; } if (!from_buffer) { - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); } @@ -580,5 +570,2 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo if (!_zip_dirent_process_winzip_aes(zde, error)) { - if (!from_buffer) { - _zip_buffer_free(buffer); - } return -1; @@ -593,4 +580,3 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo static zip_string_t * -_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) -{ +_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) { zip_uint16_t ef_len; @@ -606,3 +592,3 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) { - return str; + return str; } @@ -613,4 +599,4 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string if (_zip_string_crc32(str) == ef_crc) { - zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer); - zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL); + zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer); + zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL); @@ -629,4 +615,3 @@ _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string static bool -_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) -{ +_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) { zip_uint16_t ef_len; @@ -651,3 +636,3 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) zip_error_set(error, ZIP_ER_INTERNAL, 0); - return false; + return false; } @@ -713,4 +698,3 @@ _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) zip_int32_t -_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) -{ +_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) { zip_int32_t size; @@ -724,3 +708,3 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) { - _zip_error_set_from_source(error, src); + _zip_error_set_from_source(error, src); return -1; @@ -732,3 +716,3 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) - for (i=0; i<(local ? 2 : 3); i++) { + for (i = 0; i < (local ? 2 : 3); i++) { size += _zip_buffer_get_16(buffer); @@ -737,5 +721,5 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) if (!_zip_buffer_eof(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); + zip_error_set(error, ZIP_ER_INTERNAL, 0); _zip_buffer_free(buffer); - return -1; + return -1; } @@ -758,4 +742,3 @@ _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) int -_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) -{ +_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) { zip_uint16_t dostime, dosdate; @@ -776,5 +759,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) - if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || - (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || - (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) + if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) de->bitflags |= ZIP_GPBF_ENCODING_UTF_8; @@ -787,3 +768,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) } - if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){ + if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN) { zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error); @@ -799,6 +780,6 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (de->encryption_method == ZIP_EM_NONE) { - de->bitflags &= ~ZIP_GPBF_ENCRYPTED; + de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED; } else { - de->bitflags |= ZIP_GPBF_ENCRYPTED; + de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED; } @@ -806,3 +787,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) is_really_zip64 = _zip_dirent_needs_zip64(de, flags); - is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64; + is_zip64 = (flags & (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64) || is_really_zip64; is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256; @@ -810,41 +791,41 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (is_zip64) { - zip_uint8_t ef_zip64[EFZIP64SIZE]; - zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64)); - if (ef_buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + zip_uint8_t ef_zip64[EFZIP64SIZE]; + zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64)); + if (ef_buffer == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); _zip_ef_free(ef); - return -1; - } - - if (flags & ZIP_FL_LOCAL) { - if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->uncomp_size); - _zip_buffer_put_64(ef_buffer, de->comp_size); - } - } - else { - if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) { - if (de->uncomp_size >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->uncomp_size); - } - if (de->comp_size >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->comp_size); - } - if (de->offset >= ZIP_UINT32_MAX) { - _zip_buffer_put_64(ef_buffer, de->offset); - } - } - } - - if (!_zip_buffer_ok(ef_buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(ef_buffer); + return -1; + } + + if (flags & ZIP_FL_LOCAL) { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) { + _zip_buffer_put_64(ef_buffer, de->uncomp_size); + _zip_buffer_put_64(ef_buffer, de->comp_size); + } + } + else { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) { + if (de->uncomp_size >= ZIP_UINT32_MAX) { + _zip_buffer_put_64(ef_buffer, de->uncomp_size); + } + if (de->comp_size >= ZIP_UINT32_MAX) { + _zip_buffer_put_64(ef_buffer, de->comp_size); + } + if (de->offset >= ZIP_UINT32_MAX) { + _zip_buffer_put_64(ef_buffer, de->offset); + } + } + } + + if (!_zip_buffer_ok(ef_buffer)) { + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(ef_buffer); _zip_ef_free(ef); - return -1; - } + return -1; + } - ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH); - _zip_buffer_free(ef_buffer); - ef64->next = ef; - ef = ef64; + ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH); + _zip_buffer_free(ef_buffer); + ef64->next = ef; + ef = ef64; } @@ -853,10 +834,10 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) zip_uint8_t data[EF_WINZIP_AES_SIZE]; - zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data)); + zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data)); zip_extra_field_t *ef_winzip; - - if (ef_buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + + if (ef_buffer == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); _zip_ef_free(ef); - return -1; - } + return -1; + } @@ -864,16 +845,16 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) _zip_buffer_put(ef_buffer, "AE", 2); - _zip_buffer_put_8(ef_buffer, (de->encryption_method & 0xff)); + _zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff)); _zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method); - if (!_zip_buffer_ok(ef_buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(ef_buffer); + if (!_zip_buffer_ok(ef_buffer)) { + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(ef_buffer); _zip_ef_free(ef); - return -1; - } + return -1; + } - ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH); - _zip_buffer_free(ef_buffer); - ef_winzip->next = ef; - ef = ef_winzip; + ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH); + _zip_buffer_free(ef_buffer); + ef_winzip->next = ef; + ef = ef_winzip; } @@ -881,5 +862,5 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - _zip_ef_free(ef); - return -1; + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + _zip_ef_free(ef); + return -1; } @@ -889,6 +870,6 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if ((flags & ZIP_FL_LOCAL) == 0) { - _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby)); + _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby)); } _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed)); - _zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */ + _zip_buffer_put_16(buffer, de->bitflags); if (is_winzip_aes) { @@ -904,3 +885,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) - if (is_winzip_aes && de->uncomp_size < 20) { + if (is_winzip_aes && de->uncomp_size < 20) { _zip_buffer_put_32(buffer, 0); @@ -921,14 +902,14 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) else { - if (de->comp_size < ZIP_UINT32_MAX) { + if (de->comp_size < ZIP_UINT32_MAX) { _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); - } - else { + } + else { _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } - if (de->uncomp_size < ZIP_UINT32_MAX) { + } + if (de->uncomp_size < ZIP_UINT32_MAX) { _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); - } - else { + } + else { _zip_buffer_put_32(buffer, ZIP_UINT32_MAX); - } + } } @@ -952,6 +933,6 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - _zip_ef_free(ef); - return -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(buffer); + _zip_ef_free(ef); + return -1; } @@ -959,5 +940,5 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) { - _zip_buffer_free(buffer); - _zip_ef_free(ef); - return -1; + _zip_buffer_free(buffer); + _zip_ef_free(ef); + return -1; } @@ -968,3 +949,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (_zip_string_write(za, de->filename) < 0) { - _zip_ef_free(ef); + _zip_ef_free(ef); return -1; @@ -975,3 +956,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) { - _zip_ef_free(ef); + _zip_ef_free(ef); return -1; @@ -1000,4 +981,3 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) static time_t -_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) -{ +_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { struct tm tm; @@ -1009,9 +989,9 @@ _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) - tm.tm_year = ((ddate>>9)&127) + 1980 - 1900; - tm.tm_mon = ((ddate>>5)&15) - 1; - tm.tm_mday = ddate&31; + tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900; + tm.tm_mon = ((ddate >> 5) & 15) - 1; + tm.tm_mday = ddate & 31; - tm.tm_hour = (dtime>>11)&31; - tm.tm_min = (dtime>>5)&63; - tm.tm_sec = (dtime<<1)&62; + tm.tm_hour = (dtime >> 11) & 31; + tm.tm_min = (dtime >> 5) & 63; + tm.tm_sec = (dtime << 1) & 62; @@ -1022,4 +1002,3 @@ _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) static zip_extra_field_t * -_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) -{ +_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) { const zip_uint8_t *raw; @@ -1029,3 +1008,3 @@ _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) - if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) { + if ((raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) { /* error already set */ @@ -1034,8 +1013,8 @@ _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) - if (len+5 > ZIP_UINT16_MAX) { - zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */ - return NULL; + if (len + 5 > ZIP_UINT16_MAX) { + zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */ + return NULL; } - if ((buffer = _zip_buffer_new(NULL, len+5)) == NULL) { + if ((buffer = _zip_buffer_new(NULL, len + 5)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -1049,5 +1028,5 @@ _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return NULL; + zip_error_set(error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(buffer); + return NULL; } @@ -1062,4 +1041,3 @@ _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) zip_dirent_t * -_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) -{ +_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) { if (error == NULL) @@ -1088,7 +1066,4 @@ _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) -{ +_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) { struct tm *tm; @@ -1100,4 +1075,4 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) - *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)(((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)); @@ -1105 +1080,37 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) } + + +void +_zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) { + zip_uint16_t length; + + if (de->comp_method == ZIP_CM_LZMA) { + de->version_needed = 63; + return; + } + + if (de->comp_method == ZIP_CM_BZIP2) { + de->version_needed = 46; + return; + } + + if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) { + de->version_needed = 45; + return; + } + + if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) { + de->version_needed = 20; + return; + } + + /* directory */ + if ((length = _zip_string_length(de->filename)) > 0) { + if (de->filename->raw[length - 1] == '/') { + de->version_needed = 20; + return; + } + } + + de->version_needed = 10; +} diff --git a/src/Common/libzip/zip_discard.c b/src/Common/libzip/zip_discard.c index ef891e38..5bbf8d64 100644 --- a/src/Common/libzip/zip_discard.c +++ b/src/Common/libzip/zip_discard.c @@ -2,3 +2,3 @@ zip_discard.c -- discard and free struct zip - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -44,4 +44,3 @@ void -zip_discard(zip_t *za) -{ +zip_discard(zip_t *za) { zip_uint64_t i; @@ -63,4 +62,4 @@ zip_discard(zip_t *za) if (za->entry) { - for (i=0; i<za->nentry; i++) - _zip_entry_finalize(za->entry+i); + for (i = 0; i < za->nentry; i++) + _zip_entry_finalize(za->entry + i); free(za->entry); @@ -68,3 +67,3 @@ zip_discard(zip_t *za) - for (i=0; i<za->nopen_source; i++) { + for (i = 0; i < za->nopen_source; i++) { _zip_source_invalidate(za->open_source[i]); @@ -73,4 +72,6 @@ zip_discard(zip_t *za) + _zip_progress_free(za->progress); + zip_error_fini(&za->error); - + free(za); diff --git a/src/Common/libzip/zip_entry.c b/src/Common/libzip/zip_entry.c index 6f890068..f083412c 100644 --- a/src/Common/libzip/zip_entry.c +++ b/src/Common/libzip/zip_entry.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,4 +37,3 @@ void -_zip_entry_finalize(zip_entry_t *e) -{ +_zip_entry_finalize(zip_entry_t *e) { _zip_unchange_data(e); @@ -46,4 +45,3 @@ _zip_entry_finalize(zip_entry_t *e) void -_zip_entry_init(zip_entry_t *e) -{ +_zip_entry_init(zip_entry_t *e) { e->orig = NULL; diff --git a/src/Common/libzip/zip_err_str.c b/src/Common/libzip/zip_err_str.c index 9c9adb55..3d9ee54e 100644 --- a/src/Common/libzip/zip_err_str.c +++ b/src/Common/libzip/zip_err_str.c @@ -7,37 +7,7 @@ -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", +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 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]); @@ -48,33 +18,3 @@ const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); 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, 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, }; diff --git a/src/Common/libzip/zip_error.c b/src/Common/libzip/zip_error.c index 5f4e07dc..9ccaf91b 100644 --- a/src/Common/libzip/zip_error.c +++ b/src/Common/libzip/zip_error.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -51,4 +51,3 @@ zip_error_code_zip(const zip_error_t *error) { ZIP_EXTERN void -zip_error_fini(zip_error_t *err) -{ +zip_error_fini(zip_error_t *err) { free(err->str); @@ -59,4 +58,3 @@ zip_error_fini(zip_error_t *err) ZIP_EXTERN void -zip_error_init(zip_error_t *err) -{ +zip_error_init(zip_error_t *err) { err->zip_err = ZIP_ER_OK; @@ -67,4 +65,3 @@ zip_error_init(zip_error_t *err) ZIP_EXTERN void -zip_error_init_with_code(zip_error_t *error, int ze) -{ +zip_error_init_with_code(zip_error_t *error, int ze) { zip_error_init(error); @@ -79,3 +76,3 @@ zip_error_init_with_code(zip_error_t *error, int ze) break; - } + } } @@ -86,4 +83,4 @@ zip_error_system_type(const zip_error_t *error) { if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str) - return ZIP_ET_NONE; - + return ZIP_ET_NONE; + return _zip_err_type[error->zip_err]; @@ -93,4 +90,3 @@ zip_error_system_type(const zip_error_t *error) { void -_zip_error_clear(zip_error_t *err) -{ +_zip_error_clear(zip_error_t *err) { if (err == NULL) @@ -104,4 +100,7 @@ _zip_error_clear(zip_error_t *err) void -_zip_error_copy(zip_error_t *dst, const zip_error_t *src) -{ +_zip_error_copy(zip_error_t *dst, const zip_error_t *src) { + if (dst == NULL) { + return; + } + dst->zip_err = src->zip_err; @@ -112,4 +111,3 @@ _zip_error_copy(zip_error_t *dst, const zip_error_t *src) void -_zip_error_get(const zip_error_t *err, int *zep, int *sep) -{ +_zip_error_get(const zip_error_t *err, int *zep, int *sep) { if (zep) @@ -126,4 +124,3 @@ _zip_error_get(const zip_error_t *err, int *zep, int *sep) void -zip_error_set(zip_error_t *err, int ze, int se) -{ +zip_error_set(zip_error_t *err, int ze, int se) { if (err) { @@ -136,4 +133,3 @@ zip_error_set(zip_error_t *err, int ze, int se) void -_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) -{ +_zip_error_set_from_source(zip_error_t *err, zip_source_t *src) { _zip_error_copy(err, zip_source_error(src)); @@ -143,13 +139,12 @@ _zip_error_set_from_source(zip_error_t *err, zip_source_t *src) zip_int64_t -zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length) -{ +zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length) { int *e = (int *)data; - - if (length < sizeof(int)*2) { - return -1; + + if (length < sizeof(int) * 2) { + return -1; } - + e[0] = zip_error_code_zip(error); e[1] = zip_error_code_system(error); - return sizeof(int)*2; + return sizeof(int) * 2; } diff --git a/src/Common/libzip/zip_error_clear.c b/src/Common/libzip/zip_error_clear.c index ec45e688..2cce4505 100644 --- a/src/Common/libzip/zip_error_clear.c +++ b/src/Common/libzip/zip_error_clear.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN void -zip_error_clear(zip_t *za) -{ +zip_error_clear(zip_t *za) { if (za == NULL) diff --git a/src/Common/libzip/zip_error_get.c b/src/Common/libzip/zip_error_get.c index c2220189..1f02ed3c 100644 --- a/src/Common/libzip/zip_error_get.c +++ b/src/Common/libzip/zip_error_get.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ ZIP_EXTERN void -zip_error_get(zip_t *za, int *zep, int *sep) -{ +zip_error_get(zip_t *za, int *zep, int *sep) { _zip_error_get(&za->error, zep, sep); @@ -46,4 +45,3 @@ zip_error_get(zip_t *za, int *zep, int *sep) ZIP_EXTERN zip_error_t * -zip_get_error(zip_t *za) -{ +zip_get_error(zip_t *za) { return &za->error; @@ -53,4 +51,3 @@ zip_get_error(zip_t *za) ZIP_EXTERN zip_error_t * -zip_file_get_error(zip_file_t *f) -{ +zip_file_get_error(zip_file_t *f) { return &f->error; diff --git a/src/Common/libzip/zip_error_get_sys_type.c b/src/Common/libzip/zip_error_get_sys_type.c index 7e27bbf3..d7a594e1 100644 --- a/src/Common/libzip/zip_error_get_sys_type.c +++ b/src/Common/libzip/zip_error_get_sys_type.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_error_get_sys_type(int ze) -{ +zip_error_get_sys_type(int ze) { if (ze < 0 || ze >= _zip_nerr_str) diff --git a/src/Common/libzip/zip_error_strerror.c b/src/Common/libzip/zip_error_strerror.c index bdc1e44c..6baf900f 100644 --- a/src/Common/libzip/zip_error_strerror.c +++ b/src/Common/libzip/zip_error_strerror.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -42,4 +42,3 @@ ZIP_EXTERN const char * -zip_error_strerror(zip_error_t *err) -{ +zip_error_strerror(zip_error_t *err) { const char *zs, *ss; @@ -56,3 +55,3 @@ zip_error_strerror(zip_error_t *err) zs = _zip_err_str[err->zip_err]; - + switch (_zip_err_type[err->zip_err]) { @@ -74,10 +73,6 @@ zip_error_strerror(zip_error_t *err) else { - if ((s=(char *)malloc(strlen(ss) - + (zs ? strlen(zs)+2 : 0) + 1)) == NULL) + if ((s = (char *)malloc(strlen(ss) + (zs ? strlen(zs) + 2 : 0) + 1)) == NULL) return _zip_err_str[ZIP_ER_MEMORY]; - - sprintf(s, "%s%s%s", - (zs ? zs : ""), - (zs ? ": " : ""), - ss); + + sprintf(s, "%s%s%s", (zs ? zs : ""), (zs ? ": " : ""), ss); err->str = s; diff --git a/src/Common/libzip/zip_error_to_str.c b/src/Common/libzip/zip_error_to_str.c index 019feff8..518c0e56 100644 --- a/src/Common/libzip/zip_error_to_str.c +++ b/src/Common/libzip/zip_error_to_str.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -43,4 +43,3 @@ ZIP_EXTERN int -zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) -{ +zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { const char *zs, *ss; @@ -51,3 +50,3 @@ zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) zs = _zip_err_str[ze]; - + switch (_zip_err_type[ze]) { @@ -56,3 +55,3 @@ zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) break; - + case ZIP_ET_ZLIB: @@ -60,3 +59,3 @@ zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) break; - + default: @@ -65,4 +64,3 @@ zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) - return snprintf(buf, len, "%s%s%s", - zs, (ss ? ": " : ""), (ss ? ss : "")); + return snprintf(buf, len, "%s%s%s", zs, (ss ? ": " : ""), (ss ? ss : "")); } diff --git a/src/Common/libzip/zip_extra_field.c b/src/Common/libzip/zip_extra_field.c index a01ff790..42f97d0a 100644 --- a/src/Common/libzip/zip_extra_field.c +++ b/src/Common/libzip/zip_extra_field.c @@ -2,3 +2,3 @@ zip_extra_field.c -- manipulate extra fields - Copyright (C) 2012-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,20 +40,19 @@ zip_extra_field_t * -_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) -{ +_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) { zip_extra_field_t *head, *prev, *def; - + head = prev = NULL; - + while (ef) { - if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_ef_free(head); - return NULL; - } - - if (head == NULL) - head = def; - if (prev) - prev->next = def; - prev = def; + if ((def = _zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_ef_free(head); + return NULL; + } + + if (head == NULL) + head = def; + if (prev) + prev->next = def; + prev = def; @@ -61,3 +60,3 @@ _zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) } - + return head; @@ -67,4 +66,3 @@ _zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error) zip_extra_field_t * -_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) -{ +_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) { zip_extra_field_t *head, *prev; @@ -75,3 +73,3 @@ _zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx prev = NULL; - for (; ef; ef=(prev ? prev->next : head)) { + for (; ef; ef = (prev ? prev->next : head)) { if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) { @@ -91,3 +89,3 @@ _zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx } - + i++; @@ -103,6 +101,4 @@ _zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx - void -_zip_ef_free(zip_extra_field_t *ef) -{ +_zip_ef_free(zip_extra_field_t *ef) { zip_extra_field_t *ef2; @@ -119,6 +115,5 @@ _zip_ef_free(zip_extra_field_t *ef) const zip_uint8_t * -_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error) -{ - static const zip_uint8_t empty[1] = { '\0' }; - +_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error) { + static const zip_uint8_t empty[1] = {'\0'}; + int i; @@ -126,3 +121,3 @@ _zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t i = 0; - for (; ef; ef=ef->next) { + for (; ef; ef = ef->next) { if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) { @@ -148,4 +143,3 @@ _zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t zip_extra_field_t * -_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) -{ +_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) { zip_extra_field_t *ef2, *tt, *tail; @@ -156,6 +150,6 @@ _zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) - for (tail=to; tail->next; tail=tail->next) + for (tail = to; tail->next; tail = tail->next) ; - for (; from; from=ef2) { + for (; from; from = ef2) { ef2 = from->next; @@ -163,4 +157,4 @@ _zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) duplicate = 0; - for (tt=to; tt; tt=tt->next) { - if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) { + for (tt = to; tt; tt = tt->next) { + if (tt->id == from->id && tt->size == from->size && (tt->size == 0 || memcmp(tt->data, from->data, tt->size) == 0)) { tt->flags |= (from->flags & ZIP_EF_BOTH); @@ -183,7 +177,6 @@ _zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from) zip_extra_field_t * -_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) -{ +_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) { zip_extra_field_t *ef; - if ((ef=(zip_extra_field_t *)malloc(sizeof(*ef))) == NULL) + if ((ef = (zip_extra_field_t *)malloc(sizeof(*ef))) == NULL) return NULL; @@ -195,3 +188,3 @@ _zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_fla if (size > 0) { - if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) { + if ((ef->data = (zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) { free(ef); @@ -208,4 +201,3 @@ _zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_fla bool -_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error) -{ +_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error) { zip_buffer_t *buffer; @@ -214,26 +206,26 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_ if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return false; + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; } - + ef_head = ef = NULL; - + while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) { - zip_uint16_t fid, flen; - zip_uint8_t *ef_data; - - fid = _zip_buffer_get_16(buffer); + zip_uint16_t fid, flen; + zip_uint8_t *ef_data; + + fid = _zip_buffer_get_16(buffer); flen = _zip_buffer_get_16(buffer); - ef_data = _zip_buffer_get(buffer, flen); + ef_data = _zip_buffer_get(buffer, flen); - if (ef_data == NULL) { + if (ef_data == NULL) { zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); _zip_ef_free(ef_head); return false; - } - - if ((ef2=_zip_ef_new(fid, flen, ef_data, flags)) == NULL) { + } + + if ((ef2 = _zip_ef_new(fid, flen, ef_data, flags)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); _zip_ef_free(ef_head); @@ -270,5 +262,5 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_ else { - _zip_ef_free(ef_head); + _zip_ef_free(ef_head); } - + return true; @@ -278,27 +270,26 @@ _zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_ zip_extra_field_t * -_zip_ef_remove_internal(zip_extra_field_t *ef) -{ +_zip_ef_remove_internal(zip_extra_field_t *ef) { zip_extra_field_t *ef_head; zip_extra_field_t *prev, *next; - + ef_head = ef; prev = NULL; - + while (ef) { - if (ZIP_EF_IS_INTERNAL(ef->id)) { - next = ef->next; - if (ef_head == ef) - ef_head = next; - ef->next = NULL; - _zip_ef_free(ef); - if (prev) - prev->next = next; - ef = next; - } - else { - prev = ef; - ef = ef->next; - } + if (ZIP_EF_IS_INTERNAL(ef->id)) { + next = ef->next; + if (ef_head == ef) + ef_head = next; + ef->next = NULL; + _zip_ef_free(ef); + if (prev) + prev->next = next; + ef = next; + } + else { + prev = ef; + ef = ef->next; + } } - + return ef_head; @@ -308,4 +299,3 @@ _zip_ef_remove_internal(zip_extra_field_t *ef) zip_uint16_t -_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) -{ +_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) { zip_uint16_t size; @@ -313,5 +303,5 @@ _zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) size = 0; - for (; ef; ef=ef->next) { + for (; ef; ef = ef->next) { if (ef->flags & flags & ZIP_EF_BOTH) - size = (zip_uint16_t)(size+4+ef->size); + size = (zip_uint16_t)(size + 4 + ef->size); } @@ -323,4 +313,3 @@ _zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags) int -_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) -{ +_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) { zip_uint8_t b[4]; @@ -332,15 +321,15 @@ _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) - for (; ef; ef=ef->next) { + for (; ef; ef = ef->next) { if (ef->flags & flags & ZIP_EF_BOTH) { - _zip_buffer_set_offset(buffer, 0); - _zip_buffer_put_16(buffer, ef->id); + _zip_buffer_set_offset(buffer, 0); + _zip_buffer_put_16(buffer, ef->id); _zip_buffer_put_16(buffer, ef->size); - if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - _zip_buffer_free(buffer); - return -1; - } + if (!_zip_buffer_ok(buffer)) { + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + _zip_buffer_free(buffer); + return -1; + } if (_zip_write(za, b, 4) < 0) { - _zip_buffer_free(buffer); - return -1; + _zip_buffer_free(buffer); + return -1; } @@ -348,4 +337,4 @@ _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) if (_zip_write(za, ef->data, ef->size) < 0) { - _zip_buffer_free(buffer); - return -1; + _zip_buffer_free(buffer); + return -1; } @@ -354,3 +343,3 @@ _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) } - + _zip_buffer_free(buffer); @@ -361,4 +350,3 @@ _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags) int -_zip_read_local_ef(zip_t *za, zip_uint64_t idx) -{ +_zip_read_local_ef(zip_t *za, zip_uint64_t idx) { zip_entry_t *e; @@ -373,3 +361,3 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) - e = za->entry+idx; + e = za->entry + idx; @@ -381,3 +369,3 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) return -1; - } + } @@ -387,18 +375,18 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) } - + if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) { - return -1; + return -1; } - + fname_len = _zip_buffer_get_16(buffer); ef_len = _zip_buffer_get_16(buffer); - + if (!_zip_buffer_eof(buffer)) { - _zip_buffer_free(buffer); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + _zip_buffer_free(buffer); + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } - + _zip_buffer_free(buffer); - + if (ef_len > 0) { @@ -430,3 +418,3 @@ _zip_read_local_ef(zip_t *za, zip_uint64_t idx) e->orig->local_extra_fields_read = 1; - + if (e->changes && e->changes->local_extra_fields_read == 0) { diff --git a/src/Common/libzip/zip_extra_field_api.c b/src/Common/libzip/zip_extra_field_api.c index ed93944a..469abd2f 100644 --- a/src/Common/libzip/zip_extra_field_api.c +++ b/src/Common/libzip/zip_extra_field_api.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) -{ +zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) { zip_dirent_t *de; @@ -51,6 +50,6 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi } - + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) return -1; - + if (ZIP_IS_RDONLY(za)) { @@ -61,6 +60,6 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - + return -1; + de = za->entry[idx].changes; - + de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags); @@ -71,4 +70,3 @@ zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zi ZIP_EXTERN int -zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) -{ +zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) { zip_dirent_t *de; @@ -84,3 +82,3 @@ zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i } - + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) @@ -92,6 +90,6 @@ zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i } - + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - + return -1; + de = za->entry[idx].changes; @@ -104,5 +102,4 @@ zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i ZIP_EXTERN const zip_uint8_t * -zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) -{ - static const zip_uint8_t empty[1] = { '\0' }; +zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) { + static const zip_uint8_t empty[1] = {'\0'}; @@ -117,3 +114,3 @@ zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_u - if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) return NULL; @@ -125,3 +122,3 @@ zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_u i = 0; - for (ef=de->extra_fields; ef; ef=ef->next) { + for (ef = de->extra_fields; ef; ef = ef->next) { if (ef->flags & flags & ZIP_EF_BOTH) { @@ -145,3 +142,2 @@ zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_u return NULL; - } @@ -150,4 +146,3 @@ zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_u ZIP_EXTERN const zip_uint8_t * -zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) -{ +zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) { zip_dirent_t *de; @@ -159,3 +154,3 @@ zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, - if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) return NULL; @@ -171,4 +166,3 @@ zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, ZIP_EXTERN zip_int16_t -zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) -{ +zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) { zip_dirent_t *de; @@ -182,3 +176,3 @@ zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) - if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) return -1; @@ -190,3 +184,3 @@ zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) n = 0; - for (ef=de->extra_fields; ef; ef=ef->next) + for (ef = de->extra_fields; ef; ef = ef->next) if (ef->flags & flags & ZIP_EF_BOTH) @@ -199,4 +193,3 @@ zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) ZIP_EXTERN zip_int16_t -zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) -{ +zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) { zip_dirent_t *de; @@ -210,3 +203,3 @@ zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i - if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL) return -1; @@ -218,3 +211,3 @@ zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i n = 0; - for (ef=de->extra_fields; ef; ef=ef->next) + for (ef = de->extra_fields; ef; ef = ef->next) if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) @@ -227,4 +220,3 @@ zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_i ZIP_EXTERN int -zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) -{ +zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) { zip_dirent_t *de; @@ -241,3 +233,3 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui return -1; - + if (ZIP_IS_RDONLY(za)) { @@ -246,3 +238,3 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui } - + if (ZIP_EF_IS_INTERNAL(ef_id)) { @@ -253,4 +245,4 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) - return -1; - + return -1; + de = za->entry[idx].changes; @@ -262,3 +254,3 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui - for (; ef; ef=ef->next) { + for (; ef; ef = ef->next) { if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) { @@ -296,4 +288,4 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui } - - if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) { + + if ((ef_new = _zip_ef_new(ef_id, len, data, flags)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -316,3 +308,3 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui ef->next = ef_new; - } + } } @@ -324,3 +316,3 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui de->extra_fields = ef_new; - + return 0; @@ -329,17 +321,15 @@ zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_ui - int -_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) -{ +_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) { zip_entry_t *e; - + if (idx >= za->nentry) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - - e = za->entry+idx; - + + e = za->entry + idx; + if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD)) - return 0; + return 0; @@ -349,12 +339,12 @@ _zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) } - + if (e->changes == NULL) { - if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } } - + if (e->orig && e->orig->extra_fields) { - if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL) + if ((e->changes->extra_fields = _zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL) return -1; @@ -362,5 +352,4 @@ _zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD; - + return 0; } - diff --git a/src/Common/libzip/zip_fclose.c b/src/Common/libzip/zip_fclose.c index 25a201b1..be98cc0c 100644 --- a/src/Common/libzip/zip_fclose.c +++ b/src/Common/libzip/zip_fclose.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,6 +40,5 @@ ZIP_EXTERN int -zip_fclose(zip_file_t *zf) -{ +zip_fclose(zip_file_t *zf) { int ret; - + if (zf->src) diff --git a/src/Common/libzip/zip_fdopen.c b/src/Common/libzip/zip_fdopen.c index a058f811..b1fc22bf 100644 --- a/src/Common/libzip/zip_fdopen.c +++ b/src/Common/libzip/zip_fdopen.c @@ -2,3 +2,3 @@ zip_fdopen.c -- open read-only archive from file descriptor - Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ ZIP_EXTERN zip_t * -zip_fdopen(int fd_orig, int _flags, int *zep) -{ +zip_fdopen(int fd_orig, int _flags, int *zep) { int fd; @@ -49,7 +48,7 @@ zip_fdopen(int fd_orig, int _flags, int *zep) - if (_flags < 0 || (_flags & ZIP_TRUNCATE)) { + if (_flags < 0 || (_flags & ~(ZIP_CHECKCONS | ZIP_RDONLY))) { _zip_set_open_error(zep, NULL, ZIP_ER_INVAL); - return NULL; + return NULL; } - + /* We dup() here to avoid messing with the passed in fd. @@ -57,3 +56,3 @@ zip_fdopen(int fd_orig, int _flags, int *zep) - if ((fd=dup(fd_orig)) < 0) { + if ((fd = dup(fd_orig)) < 0) { _zip_set_open_error(zep, NULL, ZIP_ER_OPEN); @@ -62,3 +61,3 @@ zip_fdopen(int fd_orig, int _flags, int *zep) - if ((fp=fdopen(fd, "rb")) == NULL) { + if ((fp = fdopen(fd, "rb")) == NULL) { close(fd); diff --git a/src/Common/libzip/zip_file_add.c b/src/Common/libzip/zip_file_add.c index 9944c0f1..ec8ef063 100644 --- a/src/Common/libzip/zip_file_add.c +++ b/src/Common/libzip/zip_file_add.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,5 +38,5 @@ NOTE: Return type is signed so we can return -1 on error. - The index can not be larger than ZIP_INT64_MAX since the size - of the central directory cannot be larger than - ZIP_UINT64_MAX, and each entry is larger than 2 bytes. + The index can not be larger than ZIP_INT64_MAX since the size + of the central directory cannot be larger than + ZIP_UINT64_MAX, and each entry is larger than 2 bytes. */ @@ -44,4 +44,3 @@ ZIP_EXTERN zip_int64_t -zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags) -{ +zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags) { if (name == NULL || source == NULL) { @@ -50,3 +49,3 @@ zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flag } - + return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags); diff --git a/src/Common/libzip/zip_file_error_clear.c b/src/Common/libzip/zip_file_error_clear.c index be454982..666becab 100644 --- a/src/Common/libzip/zip_file_error_clear.c +++ b/src/Common/libzip/zip_file_error_clear.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN void -zip_file_error_clear(zip_file_t *zf) -{ +zip_file_error_clear(zip_file_t *zf) { if (zf == NULL) diff --git a/src/Common/libzip/zip_file_error_get.c b/src/Common/libzip/zip_file_error_get.c index be764fd5..d7e0191f 100644 --- a/src/Common/libzip/zip_file_error_get.c +++ b/src/Common/libzip/zip_file_error_get.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN void -zip_file_error_get(zip_file_t *zf, int *zep, int *sep) -{ +zip_file_error_get(zip_file_t *zf, int *zep, int *sep) { _zip_error_get(&zf->error, zep, sep); diff --git a/src/Common/libzip/zip_file_get_comment.c b/src/Common/libzip/zip_file_get_comment.c index 55e7dc28..478f3d70 100644 --- a/src/Common/libzip/zip_file_get_comment.c +++ b/src/Common/libzip/zip_file_get_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ ZIP_EXTERN const char * -zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) -{ +zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) { zip_dirent_t *de; @@ -45,6 +44,6 @@ zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_ - if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL) return NULL; - if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL) + if ((str = _zip_string_get(de->comment, &len, flags, &za->error)) == NULL) return NULL; diff --git a/src/Common/libzip/zip_file_get_external_attributes.c b/src/Common/libzip/zip_file_get_external_attributes.c index b6526cf2..e3ede740 100644 --- a/src/Common/libzip/zip_file_get_external_attributes.c +++ b/src/Common/libzip/zip_file_get_external_attributes.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -36,7 +36,6 @@ int -zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) -{ +zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) { zip_dirent_t *de; - if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, NULL)) == NULL) return -1; diff --git a/src/Common/libzip/zip_file_get_offset.c b/src/Common/libzip/zip_file_get_offset.c index 826650e5..877c179b 100644 --- a/src/Common/libzip/zip_file_get_offset.c +++ b/src/Common/libzip/zip_file_get_offset.c @@ -2,3 +2,3 @@ zip_file_get_offset.c -- get offset of file data in archive. - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,4 +37,4 @@ #include <string.h> -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> @@ -50,4 +50,3 @@ zip_uint64_t -_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) -{ +_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) { zip_uint64_t offset; @@ -55,2 +54,7 @@ _zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) + if (za->entry[idx].orig == NULL) { + zip_error_set(error, ZIP_ER_INTERNAL, 0); + return 0; + } + offset = za->entry[idx].orig->offset; @@ -63,11 +67,54 @@ _zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error) /* TODO: cache? */ - if ((size=_zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0) + if ((size = _zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0) return 0; - if (offset+(zip_uint32_t)size > ZIP_INT64_MAX) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return 0; + if (offset + (zip_uint32_t)size > ZIP_INT64_MAX) { + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; } - + return offset + (zip_uint32_t)size; } + +zip_uint64_t +_zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error) { + zip_uint64_t offset; + zip_dirent_t *entry; + + if ((offset = _zip_file_get_offset(za, index, error)) == 0) { + return 0; + } + + entry = za->entry[index].orig; + + if (offset + entry->comp_size < offset || offset + entry->comp_size > ZIP_INT64_MAX) { + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; + } + offset += entry->comp_size; + + if (entry->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + zip_uint8_t buf[4]; + if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { + _zip_error_set_from_source(error, za->src); + return 0; + } + if (zip_source_read(za->src, buf, 4) != 4) { + _zip_error_set_from_source(error, za->src); + return 0; + } + if (memcmp(buf, DATADES_MAGIC, 4) == 0) { + offset += 4; + } + offset += 12; + if (_zip_dirent_needs_zip64(entry, 0)) { + offset += 8; + } + if (offset > ZIP_INT64_MAX) { + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; + } + } + + return offset; +} diff --git a/src/Common/libzip/zip_file_rename.c b/src/Common/libzip/zip_file_rename.c index 4400938a..1eb7fac1 100644 --- a/src/Common/libzip/zip_file_rename.c +++ b/src/Common/libzip/zip_file_rename.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,7 +40,6 @@ ZIP_EXTERN int -zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) -{ +zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { const char *old_name; int old_is_dir, new_is_dir; - + if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) { @@ -55,7 +54,7 @@ zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags - if ((old_name=zip_get_name(za, idx, 0)) == NULL) + if ((old_name = zip_get_name(za, idx, 0)) == NULL) return -1; - - new_is_dir = (name != NULL && name[strlen(name)-1] == '/'); - old_is_dir = (old_name[strlen(old_name)-1] == '/'); + + new_is_dir = (name != NULL && name[strlen(name) - 1] == '/'); + old_is_dir = (old_name[strlen(old_name) - 1] == '/'); diff --git a/src/Common/libzip/zip_file_replace.c b/src/Common/libzip/zip_file_replace.c index e430efae..e42f5cd9 100644 --- a/src/Common/libzip/zip_file_replace.c +++ b/src/Common/libzip/zip_file_replace.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags) -{ +zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags) { if (idx >= za->nentry || source == NULL) { @@ -52,3 +51,2 @@ zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t - /* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ @@ -56,6 +54,5 @@ zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t zip_int64_t -_zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *source, zip_flags_t flags) -{ +_zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *source, zip_flags_t flags) { zip_uint64_t za_nentry_prev; - + if (ZIP_IS_RDONLY(za)) { @@ -68,3 +65,3 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s zip_int64_t i = -1; - + if (flags & ZIP_FL_OVERWRITE) @@ -74,3 +71,3 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s /* create and use new entry, used by zip_add */ - if ((i=_zip_add_entry(za)) < 0) + if ((i = _zip_add_entry(za)) < 0) return -1; @@ -79,6 +76,6 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s } - + if (name && _zip_set_name(za, idx, name, flags) != 0) { if (za->nentry != za_nentry_prev) { - _zip_entry_finalize(za->entry+idx); + _zip_entry_finalize(za->entry + idx); za->nentry = za_nentry_prev; @@ -90,16 +87,16 @@ _zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *s * needed for a double add of the same file name */ - _zip_unchange_data(za->entry+idx); + _zip_unchange_data(za->entry + idx); if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) { - if (za->entry[idx].changes == NULL) { - if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - } - - za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT; - za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD; + if (za->entry[idx].changes == NULL) { + if ((za->entry[idx].changes = _zip_dirent_clone(za->entry[idx].orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT; + za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD; } - + za->entry[idx].source = source; diff --git a/src/Common/libzip/zip_file_set_comment.c b/src/Common/libzip/zip_file_set_comment.c index e455fbd2..964486b3 100644 --- a/src/Common/libzip/zip_file_set_comment.c +++ b/src/Common/libzip/zip_file_set_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,5 +40,3 @@ ZIP_EXTERN int -zip_file_set_comment(zip_t *za, zip_uint64_t idx, - const char *comment, zip_uint16_t len, zip_flags_t flags) -{ +zip_file_set_comment(zip_t *za, zip_uint64_t idx, const char *comment, zip_uint16_t len, zip_flags_t flags) { zip_entry_t *e; @@ -61,3 +59,3 @@ zip_file_set_comment(zip_t *za, zip_uint64_t idx, if (len > 0) { - if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL) + if ((cstr = _zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL) return -1; @@ -69,3 +67,3 @@ zip_file_set_comment(zip_t *za, zip_uint64_t idx, - e = za->entry+idx; + e = za->entry + idx; @@ -81,13 +79,13 @@ zip_file_set_comment(zip_t *za, zip_uint64_t idx, changed = (cstr != NULL); - + if (changed) { - if (e->changes == NULL) { - if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + if (e->changes == NULL) { + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); _zip_string_free(cstr); - return -1; - } - } - e->changes->comment = cstr; - e->changes->changed |= ZIP_DIRENT_COMMENT; + return -1; + } + } + e->changes->comment = cstr; + e->changes->changed |= ZIP_DIRENT_COMMENT; } diff --git a/src/Common/libzip/zip_file_set_external_attributes.c b/src/Common/libzip/zip_file_set_external_attributes.c index b772c31e..cd46e88e 100644 --- a/src/Common/libzip/zip_file_set_external_attributes.c +++ b/src/Common/libzip/zip_file_set_external_attributes.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -36,4 +36,3 @@ ZIP_EXTERN int -zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes) -{ +zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes) { zip_entry_t *e; @@ -51,5 +50,5 @@ zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, - e = za->entry+idx; + e = za->entry + idx; - unchanged_opsys = (e->orig ? (zip_uint8_t)(e->orig->version_madeby>>8) : (zip_uint8_t)ZIP_OPSYS_DEFAULT); + unchanged_opsys = (e->orig ? (zip_uint8_t)(e->orig->version_madeby >> 8) : (zip_uint8_t)ZIP_OPSYS_DEFAULT); unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT; @@ -59,11 +58,11 @@ zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, 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->version_madeby = (zip_uint16_t)((opsys << 8) | (e->changes->version_madeby & 0xff)); + 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->version_madeby = (zip_uint16_t)((opsys << 8) | (e->changes->version_madeby & 0xff)); e->changes->ext_attrib = attributes; - e->changes->changed |= ZIP_DIRENT_ATTRIBUTES; + e->changes->changed |= ZIP_DIRENT_ATTRIBUTES; } diff --git a/src/Common/libzip/zip_file_set_mtime.c b/src/Common/libzip/zip_file_set_mtime.c index 0cdd31a6..15316d32 100644 --- a/src/Common/libzip/zip_file_set_mtime.c +++ b/src/Common/libzip/zip_file_set_mtime.c @@ -3,6 +3,6 @@ Copyright (C) 2014 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 @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -35,39 +35,39 @@ -ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t 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; - + return -1; + if (ZIP_IS_RDONLY(za)) { - zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; } - - e = za->entry+idx; + + 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; + 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) { + if (e->changes) { + e->changes->changed &= ~ZIP_DIRENT_LAST_MOD; + if (e->changes->changed == 0) { _zip_dirent_free(e->changes); - e->changes = NULL; - } - } + e->changes = NULL; + } + } } - + return 0; diff --git a/src/Common/libzip/zip_file_strerror.c b/src/Common/libzip/zip_file_strerror.c index 8366f1ea..fd4008af 100644 --- a/src/Common/libzip/zip_file_strerror.c +++ b/src/Common/libzip/zip_file_strerror.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN const char * -zip_file_strerror(zip_file_t *zf) -{ +zip_file_strerror(zip_file_t *zf) { return zip_error_strerror(&zf->error); diff --git a/src/Common/libzip/zip_filerange_crc.c b/src/Common/libzip/zip_filerange_crc.c index 775af9ad..6c4be274 100644 --- a/src/Common/libzip/zip_filerange_crc.c +++ b/src/Common/libzip/zip_filerange_crc.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,6 +39,4 @@ - int -_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error) -{ +_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error) { Bytef buf[BUFSIZE]; @@ -57,3 +55,3 @@ _zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLon } - + while (len > 0) { diff --git a/src/Common/libzip/zip_fopen.c b/src/Common/libzip/zip_fopen.c index 3adb5de6..cb45cc2a 100644 --- a/src/Common/libzip/zip_fopen.c +++ b/src/Common/libzip/zip_fopen.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,7 +38,6 @@ ZIP_EXTERN zip_file_t * -zip_fopen(zip_t *za, const char *fname, zip_flags_t flags) -{ +zip_fopen(zip_t *za, const char *fname, zip_flags_t flags) { zip_int64_t idx; - if ((idx=zip_name_locate(za, fname, flags)) < 0) + if ((idx = zip_name_locate(za, fname, flags)) < 0) return NULL; diff --git a/src/Common/libzip/zip_fopen_encrypted.c b/src/Common/libzip/zip_fopen_encrypted.c index 5eaf2b04..abcf6acd 100644 --- a/src/Common/libzip/zip_fopen_encrypted.c +++ b/src/Common/libzip/zip_fopen_encrypted.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,7 +38,6 @@ ZIP_EXTERN zip_file_t * -zip_fopen_encrypted(zip_t *za, const char *fname, zip_flags_t flags, const char *password) -{ +zip_fopen_encrypted(zip_t *za, const char *fname, zip_flags_t flags, const char *password) { zip_int64_t idx; - if ((idx=zip_name_locate(za, fname, flags)) < 0) + if ((idx = zip_name_locate(za, fname, flags)) < 0) return NULL; diff --git a/src/Common/libzip/zip_fopen_index.c b/src/Common/libzip/zip_fopen_index.c index 0fb150b2..7dcf1f7f 100644 --- a/src/Common/libzip/zip_fopen_index.c +++ b/src/Common/libzip/zip_fopen_index.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ ZIP_EXTERN zip_file_t * -zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags) -{ +zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags) { return zip_fopen_index_encrypted(za, index, flags, za->default_password); diff --git a/src/Common/libzip/zip_fopen_index_encrypted.c b/src/Common/libzip/zip_fopen_index_encrypted.c index 4c32e026..6b32008a 100644 --- a/src/Common/libzip/zip_fopen_index_encrypted.c +++ b/src/Common/libzip/zip_fopen_index_encrypted.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -43,5 +43,3 @@ static zip_file_t *_zip_file_new(zip_t *za); ZIP_EXTERN zip_file_t * -zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, - const char *password) -{ +zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, const char *password) { zip_file_t *zf; @@ -49,3 +47,3 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, - if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) + if ((src = _zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) return NULL; @@ -58,3 +56,3 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, - if ((zf=_zip_file_new(za)) == NULL) { + if ((zf = _zip_file_new(za)) == NULL) { zip_source_free(src); @@ -70,7 +68,6 @@ zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags, static zip_file_t * -_zip_file_new(zip_t *za) -{ +_zip_file_new(zip_t *za) { zip_file_t *zf; - if ((zf=(zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) { + if ((zf = (zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); diff --git a/src/Common/libzip/zip_fread.c b/src/Common/libzip/zip_fread.c index 9c1cbe0c..be46cf0c 100644 --- a/src/Common/libzip/zip_fread.c +++ b/src/Common/libzip/zip_fread.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN zip_int64_t -zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) -{ +zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) { zip_int64_t n; @@ -56,3 +55,3 @@ zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread) - if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) { + if ((n = zip_source_read(zf->src, outbuf, toread)) < 0) { _zip_error_set_from_source(&zf->error, zf->src); diff --git a/src/Common/libzip/zip_get_archive_comment.c b/src/Common/libzip/zip_get_archive_comment.c index 78f8ca09..a3d5a195 100644 --- a/src/Common/libzip/zip_get_archive_comment.c +++ b/src/Common/libzip/zip_get_archive_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN const char * -zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags) -{ +zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags) { zip_string_t *comment; @@ -51,3 +50,3 @@ zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags) - if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL) + if ((str = _zip_string_get(comment, &len, flags, &za->error)) == NULL) return NULL; diff --git a/src/Common/libzip/zip_get_archive_flag.c b/src/Common/libzip/zip_get_archive_flag.c index bffe10c1..67fe4f82 100644 --- a/src/Common/libzip/zip_get_archive_flag.c +++ b/src/Common/libzip/zip_get_archive_flag.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags) -{ +zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags) { unsigned int fl; diff --git a/src/Common/libzip/zip_get_encryption_implementation.c b/src/Common/libzip/zip_get_encryption_implementation.c index 8a027b2a..ba459d44 100644 --- a/src/Common/libzip/zip_get_encryption_implementation.c +++ b/src/Common/libzip/zip_get_encryption_implementation.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ zip_encryption_implementation -_zip_get_encryption_implementation(zip_uint16_t em, int operation) -{ +_zip_get_encryption_implementation(zip_uint16_t em, int operation) { switch (em) { @@ -46,3 +45,4 @@ _zip_get_encryption_implementation(zip_uint16_t em, int operation) return zip_source_pkware; -/* + +#if defined(HAVE_CRYPTO) case ZIP_EM_AES_128: @@ -51,3 +51,4 @@ _zip_get_encryption_implementation(zip_uint16_t em, int operation) return operation == ZIP_CODEC_DECODE ? zip_source_winzip_aes_decode : zip_source_winzip_aes_encode; -*/ +#endif + default: diff --git a/src/Common/libzip/zip_get_file_comment.c b/src/Common/libzip/zip_get_file_comment.c index d5f50bf2..44e59173 100644 --- a/src/Common/libzip/zip_get_file_comment.c +++ b/src/Common/libzip/zip_get_file_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ ZIP_EXTERN const char * -zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags) -{ +zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags) { zip_uint32_t len; @@ -44,3 +43,3 @@ zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags) - if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) { + if ((s = zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) { if (lenp) diff --git a/src/Common/libzip/zip_get_name.c b/src/Common/libzip/zip_get_name.c index d29e6365..d42f14a5 100644 --- a/src/Common/libzip/zip_get_name.c +++ b/src/Common/libzip/zip_get_name.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN const char * -zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags) -{ +zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags) { return _zip_get_name(za, idx, flags, &za->error); @@ -47,4 +46,3 @@ zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags) const char * -_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) -{ +_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) { zip_dirent_t *de; @@ -52,6 +50,6 @@ _zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error - if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL) + if ((de = _zip_get_dirent(za, idx, flags, error)) == NULL) return NULL; - if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL) + if ((str = _zip_string_get(de->filename, NULL, flags, error)) == NULL) return NULL; diff --git a/src/Common/libzip/zip_get_num_entries.c b/src/Common/libzip/zip_get_num_entries.c index c8644a4c..78f30dca 100644 --- a/src/Common/libzip/zip_get_num_entries.c +++ b/src/Common/libzip/zip_get_num_entries.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN zip_int64_t -zip_get_num_entries(zip_t *za, zip_flags_t flags) -{ +zip_get_num_entries(zip_t *za, zip_flags_t flags) { zip_uint64_t n; @@ -47,3 +46,3 @@ zip_get_num_entries(zip_t *za, zip_flags_t flags) n = za->nentry; - while (n>0 && za->entry[n-1].orig == NULL) + while (n > 0 && za->entry[n - 1].orig == NULL) --n; diff --git a/src/Common/libzip/zip_get_num_files.c b/src/Common/libzip/zip_get_num_files.c index cf96353f..3ccf400c 100644 --- a/src/Common/libzip/zip_get_num_files.c +++ b/src/Common/libzip/zip_get_num_files.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN int -zip_get_num_files(zip_t *za) -{ +zip_get_num_files(zip_t *za) { if (za == NULL) diff --git a/src/Common/libzip/zip_hash.c b/src/Common/libzip/zip_hash.c index 23f9708d..0d9e9961 100644 --- a/src/Common/libzip/zip_hash.c +++ b/src/Common/libzip/zip_hash.c @@ -2,3 +2,3 @@ zip_hash.c -- hash table string -> uint64 - Copyright (C) 2015-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2015-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -33,5 +33,17 @@ +#include "zipint.h" #include <stdlib.h> #include <string.h> -#include "zipint.h" + +/* parameter for the string hash function */ +#define HASH_MULTIPLIER 33 +#define HASH_START 5381 + +/* hash table's fill ratio is kept between these by doubling/halfing its size as necessary */ +#define HASH_MAX_FILL .75 +#define HASH_MIN_FILL .01 + +/* but hash table size is kept between these */ +#define HASH_MIN_SIZE 256 +#define HASH_MAX_SIZE 0x80000000ul @@ -42,2 +54,3 @@ struct zip_hash_entry { struct zip_hash_entry *next; + zip_uint32_t hash_value; }; @@ -46,3 +59,4 @@ typedef struct zip_hash_entry zip_hash_entry_t; struct zip_hash { - zip_uint16_t table_size; + zip_uint32_t table_size; + zip_uint64_t nentries; zip_hash_entry_t **table; @@ -50,19 +64,108 @@ struct zip_hash { -zip_hash_t * -_zip_hash_new(zip_uint16_t table_size, zip_error_t *error) -{ - zip_hash_t *hash; - if (table_size == 0) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - return NULL; +/* free list of entries */ +static void +free_list(zip_hash_entry_t *entry) { + while (entry != NULL) { + zip_hash_entry_t *next = entry->next; + free(entry); + entry = next; } +} + + +/* compute hash of string, full 32 bit value */ +static zip_uint32_t +hash_string(const zip_uint8_t *name) { + zip_uint64_t value = HASH_START; - if ((hash=(zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) { + if (name == NULL) { + return 0; + } + + while (*name != 0) { + value = (zip_uint64_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % 0x100000000ul); + name++; + } + + return (zip_uint32_t)value; +} + + +/* resize hash table; new_size must be a power of 2, can be larger or smaller than current size */ +static bool +hash_resize(zip_hash_t *hash, zip_uint32_t new_size, zip_error_t *error) { + zip_hash_entry_t **new_table; + + if (new_size == hash->table_size) { + return true; + } + + if ((new_table = (zip_hash_entry_t **)calloc(new_size, sizeof(zip_hash_entry_t *))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; + return false; } - hash->table_size = table_size; - if ((hash->table=(zip_hash_entry_t**)calloc(table_size, sizeof(zip_hash_entry_t *))) == NULL) { - free(hash); + + if (hash->nentries > 0) { + zip_uint32_t i; + + for (i = 0; i < hash->table_size; i++) { + zip_hash_entry_t *entry = hash->table[i]; + while (entry) { + zip_hash_entry_t *next = entry->next; + + zip_uint32_t new_index = entry->hash_value % new_size; + + entry->next = new_table[new_index]; + new_table[new_index] = entry; + + entry = next; + } + } + } + + free(hash->table); + hash->table = new_table; + hash->table_size = new_size; + + return true; +} + + +static zip_uint32_t +size_for_capacity(zip_uint64_t capacity) { + double needed_size = capacity / HASH_MAX_FILL; + zip_uint32_t v; + + if (needed_size > ZIP_UINT32_MAX) { + v = ZIP_UINT32_MAX; + } + else { + v = (zip_uint32_t)needed_size; + } + + if (v > HASH_MAX_SIZE) { + return HASH_MAX_SIZE; + } + + /* From Bit Twiddling Hacks by Sean Eron Anderson <seander@cs.stanford.edu> + (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2). */ + + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + + return v; +} + + +zip_hash_t * +_zip_hash_new(zip_error_t *error) { + zip_hash_t *hash; + + if ((hash = (zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -71,2 +174,6 @@ _zip_hash_new(zip_uint16_t table_size, zip_error_t *error) + hash->table_size = 0; + hash->nentries = 0; + hash->table = NULL; + return hash; @@ -74,17 +181,6 @@ _zip_hash_new(zip_uint16_t table_size, zip_error_t *error) -static void -_free_list(zip_hash_entry_t *entry) -{ - zip_hash_entry_t *next; - do { - next = entry->next; - free(entry); - entry = next; - } while (entry != NULL); -} void -_zip_hash_free(zip_hash_t *hash) -{ - zip_uint16_t i; +_zip_hash_free(zip_hash_t *hash) { + zip_uint32_t i; @@ -94,8 +190,10 @@ _zip_hash_free(zip_hash_t *hash) - for (i=0; i<hash->table_size; i++) { - if (hash->table[i] != NULL) { - _free_list(hash->table[i]); + if (hash->table != NULL) { + for (i = 0; i < hash->table_size; i++) { + if (hash->table[i] != NULL) { + free_list(hash->table[i]); + } } + free(hash->table); } - free(hash->table); free(hash); @@ -103,18 +201,2 @@ _zip_hash_free(zip_hash_t *hash) -static zip_uint16_t -_hash_string(const zip_uint8_t *name, zip_uint16_t size) -{ -#define HASH_MULTIPLIER 33 - zip_uint16_t value = 5381; - - if (name == NULL) - return 0; - - while (*name != 0) { - value = (zip_uint16_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % size); - name++; - } - - return value; -} @@ -122,5 +204,4 @@ _hash_string(const zip_uint8_t *name, zip_uint16_t size) bool -_zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error) -{ - zip_uint16_t hash_value; +_zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error) { + zip_uint32_t hash_value, table_index; zip_hash_entry_t *entry; @@ -132,5 +213,13 @@ _zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip - hash_value = _hash_string(name, hash->table_size); - for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) { - if (strcmp((const char *)name, (const char *)entry->name) == 0) { + if (hash->table_size == 0) { + if (!hash_resize(hash, HASH_MIN_SIZE, error)) { + return false; + } + } + + hash_value = hash_string(name); + table_index = hash_value % hash->table_size; + + for (entry = hash->table[table_index]; entry != NULL; entry = entry->next) { + if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) { if (((flags & ZIP_FL_UNCHANGED) && entry->orig_index != -1) || entry->current_index != -1) { @@ -146,3 +235,3 @@ _zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip if (entry == NULL) { - if ((entry=(zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) { + if ((entry = (zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -151,5 +240,12 @@ _zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip entry->name = name; - entry->next = hash->table[hash_value]; - hash->table[hash_value] = entry; + entry->next = hash->table[table_index]; + hash->table[table_index] = entry; + entry->hash_value = hash_value; entry->orig_index = -1; + hash->nentries++; + if (hash->nentries > hash->table_size * HASH_MAX_FILL && hash->table_size < HASH_MAX_SIZE) { + if (!hash_resize(hash, hash->table_size * 2, error)) { + return false; + } + } } @@ -164,7 +260,7 @@ _zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip + /* remove entry from hash, error if not found */ bool -_zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error) -{ - zip_uint16_t hash_value; +_zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error) { + zip_uint32_t hash_value, index; zip_hash_entry_t *entry, *previous; @@ -176,24 +272,33 @@ _zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error) - hash_value = _hash_string(name, hash->table_size); - previous = NULL; - entry = hash->table[hash_value]; - while (entry) { - if (strcmp((const char *)name, (const char *)entry->name) == 0) { - if (entry->orig_index == -1) { - if (previous) { - previous->next = entry->next; + if (hash->nentries > 0) { + hash_value = hash_string(name); + index = hash_value % hash->table_size; + previous = NULL; + entry = hash->table[index]; + while (entry) { + if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) { + if (entry->orig_index == -1) { + if (previous) { + previous->next = entry->next; + } + else { + hash->table[index] = entry->next; + } + free(entry); + hash->nentries--; + if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) { + if (!hash_resize(hash, hash->table_size / 2, error)) { + return false; + } + } } else { - hash->table[hash_value] = entry->next; + entry->current_index = -1; } - free(entry); + return true; } - else { - entry->current_index = -1; - } - return true; + previous = entry; + entry = entry->next; } - previous = entry; - entry = entry->next; - }; + } @@ -203,7 +308,7 @@ _zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error) + /* find value for entry in hash, -1 if not found */ zip_int64_t -_zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error) -{ - zip_uint16_t hash_value; +_zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error) { + zip_uint32_t hash_value, index; zip_hash_entry_t *entry; @@ -215,16 +320,19 @@ _zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, z - hash_value = _hash_string(name, hash->table_size); - for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) { - if (strcmp((const char *)name, (const char *)entry->name) == 0) { - if (flags & ZIP_FL_UNCHANGED) { - if (entry->orig_index != -1) { - return entry->orig_index; + if (hash->nentries > 0) { + hash_value = hash_string(name); + index = hash_value % hash->table_size; + for (entry = hash->table[index]; entry != NULL; entry = entry->next) { + if (strcmp((const char *)name, (const char *)entry->name) == 0) { + if (flags & ZIP_FL_UNCHANGED) { + if (entry->orig_index != -1) { + return entry->orig_index; + } } - } - else { - if (entry->current_index != -1) { - return entry->current_index; + else { + if (entry->current_index != -1) { + return entry->current_index; + } } + break; } - break; } @@ -233,11 +341,33 @@ _zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, z zip_error_set(error, ZIP_ER_NOENT, 0); - return -1; + return -1; } -void -_zip_hash_revert(zip_hash_t *hash) -{ - zip_uint16_t i; + +bool +_zip_hash_reserve_capacity(zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error) { + zip_uint32_t new_size; + + if (capacity == 0) { + return true; + } + + new_size = size_for_capacity(capacity); + + if (new_size <= hash->table_size) { + return true; + } + + if (!hash_resize(hash, new_size, error)) { + return false; + } + + return true; +} + + +bool +_zip_hash_revert(zip_hash_t *hash, zip_error_t *error) { + zip_uint32_t i; zip_hash_entry_t *entry, *previous; - + for (i = 0; i < hash->table_size; i++) { @@ -258,2 +388,3 @@ _zip_hash_revert(zip_hash_t *hash) free(p); + hash->nentries--; } @@ -266,2 +397,14 @@ _zip_hash_revert(zip_hash_t *hash) } + + if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) { + zip_uint32_t new_size = hash->table_size / 2; + while (hash->nentries < new_size * HASH_MIN_FILL && new_size > HASH_MIN_SIZE) { + new_size /= 2; + } + if (!hash_resize(hash, new_size, error)) { + return false; + } + } + + return true; } diff --git a/src/Common/libzip/zip_io_util.c b/src/Common/libzip/zip_io_util.c index 53a5dd26..77be8f06 100644 --- a/src/Common/libzip/zip_io_util.c +++ b/src/Common/libzip/zip_io_util.c @@ -3,6 +3,6 @@ Copyright (C) 1999-2016 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 @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ int -_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error) -{ +_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error) { zip_int64_t n; @@ -63,6 +62,5 @@ _zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *e zip_uint8_t * -_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error) -{ +_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error) { zip_uint8_t *r; - + if (length == 0 && !nulp) { @@ -78,9 +76,9 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp if (buffer) { - zip_uint8_t *data = _zip_buffer_get(buffer, length); - - if (data == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - free(r); - return NULL; - } + zip_uint8_t *data = _zip_buffer_get(buffer, length); + + if (data == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + free(r); + return NULL; + } memcpy(r, data, length); @@ -98,3 +96,3 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp r[length] = 0; - for (o=r; o<r+length; o++) + for (o = r; o < r + length; o++) if (*o == '\0') @@ -108,4 +106,3 @@ _zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp zip_string_t * -_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool nulp, zip_error_t *error) -{ +_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool nulp, zip_error_t *error) { zip_uint8_t *raw; @@ -113,3 +110,3 @@ _zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool - if ((raw=_zip_read_data(buffer, src, len, nulp, error)) == NULL) + if ((raw = _zip_read_data(buffer, src, len, nulp, error)) == NULL) return NULL; @@ -123,15 +120,14 @@ _zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool int -_zip_write(zip_t *za, const void *data, zip_uint64_t length) -{ +_zip_write(zip_t *za, const void *data, zip_uint64_t length) { zip_int64_t n; - + if ((n = zip_source_write(za->src, data, length)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } if ((zip_uint64_t)n != length) { - zip_error_set(&za->error, ZIP_ER_WRITE, EINTR); - return -1; + zip_error_set(&za->error, ZIP_ER_WRITE, EINTR); + return -1; } - + return 0; diff --git a/src/Common/libzip/zip_memdup.c b/src/Common/libzip/zip_memdup.c index cc6d767d..9d7949d4 100644 --- a/src/Common/libzip/zip_memdup.c +++ b/src/Common/libzip/zip_memdup.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ void * -_zip_memdup(const void *mem, size_t len, zip_error_t *error) -{ +_zip_memdup(const void *mem, size_t len, zip_error_t *error) { void *ret; diff --git a/src/Common/libzip/zip_name_locate.c b/src/Common/libzip/zip_name_locate.c index 706093f1..6713cabe 100644 --- a/src/Common/libzip/zip_name_locate.c +++ b/src/Common/libzip/zip_name_locate.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -43,4 +43,3 @@ ZIP_EXTERN zip_int64_t -zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) -{ +zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) { return _zip_name_locate(za, fname, flags, &za->error); @@ -50,4 +49,3 @@ zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) zip_int64_t -_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) -{ +_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error) { int (*cmp)(const char *, const char *); @@ -64,3 +62,3 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e - if (flags & (ZIP_FL_NOCASE|ZIP_FL_NODIR|ZIP_FL_ENC_CP437)) { + if (flags & (ZIP_FL_NOCASE | ZIP_FL_NODIR | ZIP_FL_ENC_CP437)) { /* can't use hash table */ @@ -68,5 +66,5 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e - for (i=0; i<za->nentry; i++) { + for (i = 0; i < za->nentry; i++) { fn = _zip_get_name(za, i, flags, error); - + /* newly added (partially filled) entry or error */ @@ -74,3 +72,3 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e continue; - + if (flags & ZIP_FL_NODIR) { @@ -78,5 +76,5 @@ _zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *e if (p) - fn = p+1; + fn = p + 1; } - + if (cmp(fname, fn) == 0) { diff --git a/src/Common/libzip/zip_new.c b/src/Common/libzip/zip_new.c index c05c2a3c..19155f4e 100644 --- a/src/Common/libzip/zip_new.c +++ b/src/Common/libzip/zip_new.c @@ -2,3 +2,3 @@ zip_new.c -- create and init struct zip - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -44,4 +44,3 @@ zip_t * -_zip_new(zip_error_t *error) -{ +_zip_new(zip_error_t *error) { zip_t *za; @@ -54,3 +53,3 @@ _zip_new(zip_error_t *error) - if ((za->names = _zip_hash_new(ZIP_HASH_TABLE_SIZE, error)) == NULL) { + if ((za->names = _zip_hash_new(error)) == NULL) { free(za); @@ -70,4 +69,4 @@ _zip_new(zip_error_t *error) za->open_source = NULL; - za->progress_callback = NULL; - + za->progress = NULL; + return za; diff --git a/src/Common/libzip/zip_open.c b/src/Common/libzip/zip_open.c index f62f95f6..1886c9d2 100644 --- a/src/Common/libzip/zip_open.c +++ b/src/Common/libzip/zip_open.c @@ -2,3 +2,3 @@ zip_open.c -- open zip archive by name - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -34,3 +34,2 @@ -#include <sys/stat.h> #include <limits.h> @@ -39,2 +38,3 @@ #include <string.h> +#include <sys/stat.h> @@ -60,4 +60,3 @@ static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip ZIP_EXTERN zip_t * -zip_open(const char *fn, int _flags, int *zep) -{ +zip_open(const char *fn, int _flags, int *zep) { zip_t *za; @@ -86,4 +85,3 @@ zip_open(const char *fn, int _flags, int *zep) ZIP_EXTERN zip_t * -zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) -{ +zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) { static zip_int64_t needed_support_read = -1; @@ -97,3 +95,3 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; + return NULL; } @@ -103,14 +101,14 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) if (needed_support_read == -1) { - needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1); - needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); + needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1); + needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); } if ((supported & needed_support_read) != needed_support_read) { - zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); - return NULL; + zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); + return NULL; } if ((supported & needed_support_write) != needed_support_write) { - flags |= ZIP_RDONLY; + flags |= ZIP_RDONLY; } - if ((flags & (ZIP_RDONLY|ZIP_TRUNCATE)) == (ZIP_RDONLY|ZIP_TRUNCATE)) { + if ((flags & (ZIP_RDONLY | ZIP_TRUNCATE)) == (ZIP_RDONLY | ZIP_TRUNCATE)) { zip_error_set(error, ZIP_ER_RDONLY, 0); @@ -159,12 +157,5 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error) -ZIP_EXTERN void -zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback) -{ - za->progress_callback = progress_callback; -} - zip_t * -_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) -{ +_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) { zip_t *za; @@ -187,3 +178,3 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) if (len == 0) { - if ((za=_zip_allocate_new(src, flags, error)) == NULL) { + if ((za = _zip_allocate_new(src, flags, error)) == NULL) { zip_source_free(src); @@ -195,4 +186,4 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) - if ((za=_zip_allocate_new(src, flags, error)) == NULL) { - return NULL; + if ((za = _zip_allocate_new(src, flags, error)) == NULL) { + return NULL; } @@ -200,3 +191,3 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) if ((cdir = _zip_find_central_dir(za, len)) == NULL) { - _zip_error_copy(error, &za->error); + _zip_error_copy(error, &za->error); /* keep src so discard does not get rid of it */ @@ -214,2 +205,4 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) + _zip_hash_reserve_capacity(za->names, za->nentry, &za->error); + for (idx = 0; idx < za->nentry; idx++) { @@ -217,6 +210,6 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) if (name == NULL) { - /* keep src so discard does not get rid of it */ - zip_source_keep(src); - zip_discard(za); - return NULL; + /* keep src so discard does not get rid of it */ + zip_source_keep(src); + zip_discard(za); + return NULL; } @@ -241,4 +234,3 @@ _zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error) void -_zip_set_open_error(int *zep, const zip_error_t *err, int ze) -{ +_zip_set_open_error(int *zep, const zip_error_t *err, int ze) { if (err) { @@ -262,4 +254,3 @@ _zip_set_open_error(int *zep, const zip_error_t *err, int ze) static zip_cdir_t * -_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) -{ +_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error) { zip_cdir_t *cd; @@ -283,8 +274,8 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) { - _zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN); - cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error); + _zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN); + cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error); } else { - _zip_buffer_set_offset(buffer, eocd_offset); - cd = _zip_read_eocd(buffer, buf_offset, za->flags, error); + _zip_buffer_set_offset(buffer, eocd_offset); + cd = _zip_read_eocd(buffer, buf_offset, za->flags, error); } @@ -305,19 +296,19 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (comment_len || (za->open_flags & ZIP_CHECKCONS)) { - zip_uint64_t tail_len; + zip_uint64_t tail_len; - _zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN); - tail_len = _zip_buffer_left(buffer); + _zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN); + tail_len = _zip_buffer_left(buffer); - if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_cdir_free(cd); - return NULL; - } + if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) { + zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_cdir_free(cd); + return NULL; + } - if (comment_len) { - if ((cd->comment=_zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { - _zip_cdir_free(cd); - return NULL; - } - } + if (comment_len) { + if ((cd->comment = _zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { + _zip_cdir_free(cd); + return NULL; + } + } } @@ -325,25 +316,25 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (cd->offset >= buf_offset) { - zip_uint8_t *data; + zip_uint8_t *data; /* if buffer already read in, use it */ - _zip_buffer_set_offset(buffer, cd->offset - buf_offset); - - if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_cdir_free(cd); - return NULL; - } - if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - _zip_cdir_free(cd); - return NULL; - } + _zip_buffer_set_offset(buffer, cd->offset - buf_offset); + + if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) { + zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_cdir_free(cd); + return NULL; + } + if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_cdir_free(cd); + return NULL; + } } else { - cd_buffer = NULL; + cd_buffer = NULL; - if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - _zip_cdir_free(cd); - return NULL; - } + if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) { + _zip_error_set_from_source(error, za->src); + _zip_cdir_free(cd); + return NULL; + } @@ -351,3 +342,3 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) { - zip_error_set(error, ZIP_ER_NOZIP, 0); + zip_error_set(error, ZIP_ER_NOZIP, 0); _zip_cdir_free(cd); @@ -358,6 +349,6 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err left = (zip_uint64_t)cd->size; - i=0; + i = 0; while (left > 0) { bool grown = false; - zip_int64_t entry_size; + zip_int64_t entry_size; @@ -379,3 +370,3 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err - if ((cd->entry[i].orig=_zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) { + if ((cd->entry[i].orig = _zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) { if (grown && zip_error_code_zip(error) == ZIP_ER_NOZIP) { @@ -384,3 +375,3 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err _zip_cdir_free(cd); - _zip_buffer_free(cd_buffer); + _zip_buffer_free(cd_buffer); return NULL; @@ -388,3 +379,3 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err i++; - left -= (zip_uint64_t)entry_size; + left -= (zip_uint64_t)entry_size; } @@ -392,6 +383,6 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (i != cd->nentry || left > 0) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(cd_buffer); - _zip_cdir_free(cd); - return NULL; + zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_buffer_free(cd_buffer); + _zip_cdir_free(cd); + return NULL; } @@ -399,25 +390,24 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err if (za->open_flags & ZIP_CHECKCONS) { - bool ok; - - if (cd_buffer) { - ok = _zip_buffer_eof(cd_buffer); - } - else { - zip_int64_t offset = zip_source_tell(za->src); - - if (offset < 0) { - _zip_error_set_from_source(error, za->src); - _zip_buffer_free(cd_buffer); - _zip_cdir_free(cd); - return NULL; - } - ok = ((zip_uint64_t)offset == cd->offset + cd->size); - } - - if (!ok) { - zip_error_set(error, ZIP_ER_INCONS, 0); - _zip_buffer_free(cd_buffer); - _zip_cdir_free(cd); - return NULL; - } + bool ok; + + if (cd_buffer) { + ok = _zip_buffer_eof(cd_buffer); + } + else { + zip_int64_t offset = zip_source_tell(za->src); + + if (offset < 0) { + _zip_error_set_from_source(error, za->src); + _zip_cdir_free(cd); + return NULL; + } + ok = ((zip_uint64_t)offset == cd->offset + cd->size); + } + + if (!ok) { + zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_buffer_free(cd_buffer); + _zip_cdir_free(cd); + return NULL; + } } @@ -436,4 +426,3 @@ _zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_err static zip_int64_t -_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) -{ +_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) { zip_uint64_t i; @@ -450,3 +439,3 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) - for (i=0; i<cd->nentry; i++) { + for (i = 0; i < cd->nentry; i++) { if (cd->entry[i].orig->offset < min) @@ -458,4 +447,3 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) - j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size - + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE; + j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE; if (j > max) @@ -467,5 +455,5 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) - if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, za->src); - return -1; + if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) { + _zip_error_set_from_source(error, za->src); + return -1; } @@ -490,3 +478,3 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) - return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX; + return (max - min) < ZIP_INT64_MAX ? (zip_int64_t)(max - min) : ZIP_INT64_MAX; } @@ -499,4 +487,3 @@ _zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error) static int -_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) -{ +_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) { if ((central->version_needed < local->version_needed) @@ -507,13 +494,9 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) #endif - || (central->comp_method != local->comp_method) - || (central->last_mod != local->last_mod) - || !_zip_string_equal(central->filename, local->filename)) + || (central->comp_method != local->comp_method) || (central->last_mod != local->last_mod) || !_zip_string_equal(central->filename, local->filename)) return -1; - if ((central->crc != local->crc) || (central->comp_size != local->comp_size) - || (central->uncomp_size != local->uncomp_size)) { + if ((central->crc != local->crc) || (central->comp_size != local->comp_size) || (central->uncomp_size != local->uncomp_size)) { /* InfoZip stores valid values in local header even when data descriptor is used. This is in violation of the appnote. */ - if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 - || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) + if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) return -1; @@ -526,4 +509,3 @@ _zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local) static zip_t * -_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) -{ +_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) { zip_t *za; @@ -537,4 +519,4 @@ _zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) if (flags & ZIP_RDONLY) { - za->flags |= ZIP_AFL_RDONLY; - za->ch_flags |= ZIP_AFL_RDONLY; + za->flags |= ZIP_AFL_RDONLY; + za->ch_flags |= ZIP_AFL_RDONLY; } @@ -548,4 +530,3 @@ _zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error) static exists_t -_zip_file_exists(zip_source_t *src, zip_error_t *error) -{ +_zip_file_exists(zip_source_t *src, zip_error_t *error) { struct zip_stat st; @@ -554,4 +535,4 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) if (zip_source_stat(src, &st) != 0) { - zip_error_t *src_error = zip_source_error(src); - if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) { + zip_error_t *src_error = zip_source_error(src); + if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) { return EXISTS_NOT; @@ -567,4 +548,3 @@ _zip_file_exists(zip_source_t *src, zip_error_t *error) static zip_cdir_t * -_zip_find_central_dir(zip_t *za, zip_uint64_t len) -{ +_zip_find_central_dir(zip_t *za, zip_uint64_t len) { zip_cdir_t *cdir, *cdirnew; @@ -580,3 +560,3 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) zip_error_set(&za->error, ZIP_ER_NOZIP, 0); - return NULL; + return NULL; } @@ -593,4 +573,4 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) if ((buf_offset = zip_source_tell(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return NULL; + _zip_error_set_from_source(&za->error, za->src); + return NULL; } @@ -598,3 +578,3 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) { - return NULL; + return NULL; } @@ -604,4 +584,4 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) if (buflen >= CDBUFSIZE) { - /* EOCD64 locator is before EOCD, so leave place for it */ - _zip_buffer_set_offset(buffer, EOCD64LOCLEN); + /* EOCD64 locator is before EOCD, so leave place for it */ + _zip_buffer_set_offset(buffer, EOCD64LOCLEN); } @@ -610,33 +590,33 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) match = _zip_buffer_get(buffer, 0); - while ((match=_zip_memmem(match, _zip_buffer_left(buffer)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) { - _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); - if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) { - if (cdir) { - if (best <= 0) { - best = _zip_checkcons(za, cdir, &error); - } - - a = _zip_checkcons(za, cdirnew, &error); - if (best < a) { - _zip_cdir_free(cdir); - cdir = cdirnew; - best = a; - } - else { - _zip_cdir_free(cdirnew); - } - } - else { - cdir = cdirnew; - if (za->open_flags & ZIP_CHECKCONS) - best = _zip_checkcons(za, cdir, &error); - else { - best = 0; - } - } - cdirnew = NULL; - } - - match++; - _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); + while ((match = _zip_memmem(match, _zip_buffer_left(buffer) - (EOCDLEN - 4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) { + _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); + if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) { + if (cdir) { + if (best <= 0) { + best = _zip_checkcons(za, cdir, &error); + } + + a = _zip_checkcons(za, cdirnew, &error); + if (best < a) { + _zip_cdir_free(cdir); + cdir = cdirnew; + best = a; + } + else { + _zip_cdir_free(cdirnew); + } + } + else { + cdir = cdirnew; + if (za->open_flags & ZIP_CHECKCONS) + best = _zip_checkcons(za, cdir, &error); + else { + best = 0; + } + } + cdirnew = NULL; + } + + match++; + _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer))); } @@ -646,5 +626,5 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) if (best < 0) { - _zip_error_copy(&za->error, &error); - _zip_cdir_free(cdir); - return NULL; + _zip_error_copy(&za->error, &error); + _zip_cdir_free(cdir); + return NULL; } @@ -656,4 +636,3 @@ _zip_find_central_dir(zip_t *za, zip_uint64_t len) static unsigned char * -_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) -{ +_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { const unsigned char *p; @@ -662,6 +641,5 @@ _zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little return NULL; - p = big-1; - while ((p=(const unsigned char *) - memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) { - if (memcmp(p+1, little+1, littlelen-1)==0) + p = big - 1; + while ((p = (const unsigned char *)memchr(p + 1, little[0], (size_t)(big - (p + 1)) + (size_t)(biglen - littlelen) + 1)) != NULL) { + if (memcmp(p + 1, little + 1, littlelen - 1) == 0) return (unsigned char *)p; @@ -674,4 +652,3 @@ _zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little static zip_cdir_t * -_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) -{ +_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { zip_cdir_t *cd; @@ -706,8 +683,8 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags - if (offset+size < offset) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; + if (offset + size < offset) { + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; } - if (offset+size > buf_offset + eocd_offset) { + if (offset + size > buf_offset + eocd_offset) { /* cdir spans past EOCD record */ @@ -717,3 +694,3 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags - if ((flags & ZIP_CHECKCONS) && offset+size != buf_offset + eocd_offset) { + if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { zip_error_set(error, ZIP_ER_INCONS, 0); @@ -722,3 +699,3 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags - if ((cd=_zip_cdir_new(nentry, error)) == NULL) + if ((cd = _zip_cdir_new(nentry, error)) == NULL) return NULL; @@ -734,4 +711,3 @@ _zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags static zip_cdir_t * -_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) -{ +_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error) { zip_cdir_t *cd; @@ -753,4 +729,4 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; } @@ -763,14 +739,14 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse 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; + _zip_buffer_set_offset(buffer, eocd_offset - buf_offset); + free_buffer = false; } else { - if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) { - _zip_error_set_from_source(error, src); - return NULL; - } - if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) { - return NULL; - } - free_buffer = true; + if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) { + _zip_error_set_from_source(error, src); + return NULL; + } + if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) { + return NULL; + } + free_buffer = true; } @@ -779,5 +755,5 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse zip_error_set(error, ZIP_ER_INCONS, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } + if (free_buffer) { + _zip_buffer_free(buffer); + } return NULL; @@ -789,6 +765,6 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse zip_error_set(error, ZIP_ER_INCONS, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; + if (free_buffer) { + _zip_buffer_free(buffer); + } + return NULL; } @@ -811,2 +787,5 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse zip_error_set(error, ZIP_ER_INCONS, 0); + if (free_buffer) { + _zip_buffer_free(buffer); + } return NULL; @@ -815,2 +794,5 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse zip_error_set(error, ZIP_ER_MULTIDISK, 0); + if (free_buffer) { + _zip_buffer_free(buffer); + } return NULL; @@ -823,5 +805,5 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse zip_error_set(error, ZIP_ER_MULTIDISK, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } + if (free_buffer) { + _zip_buffer_free(buffer); + } return NULL; @@ -833,7 +815,7 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse if (!_zip_buffer_ok(buffer)) { - zip_error_set(error, ZIP_ER_INTERNAL, 0); - if (free_buffer) { - _zip_buffer_free(buffer); - } - return NULL; + zip_error_set(error, ZIP_ER_INTERNAL, 0); + if (free_buffer) { + _zip_buffer_free(buffer); + } + return NULL; } @@ -841,10 +823,15 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse if (free_buffer) { - _zip_buffer_free(buffer); + _zip_buffer_free(buffer); } - if (offset > ZIP_INT64_MAX || offset+size < offset) { - zip_error_set(error, ZIP_ER_SEEK, EFBIG); - return NULL; + if (offset > ZIP_INT64_MAX || offset + size < offset) { + zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + if (offset + size > buf_offset + eocd_offset) { + /* cdir spans past EOCD record */ + zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; } - if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) { + if ((flags & ZIP_CHECKCONS) && offset + size != buf_offset + eocd_offset) { zip_error_set(error, ZIP_ER_INCONS, 0); @@ -853,3 +840,3 @@ _zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offse - if ((cd=_zip_cdir_new(nentry, error)) == 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 new file mode 100644 index 00000000..46c8bb81 --- /dev/null +++ b/src/Common/libzip/zip_progress.c @@ -0,0 +1,183 @@ +/* + zip_progress.c -- progress reporting + Copyright (C) 2017 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 <stdlib.h> + + +#define _ZIP_COMPILING_DEPRECATED +#include "zipint.h" + +struct zip_progress { + zip_t *za; + zip_progress_callback callback; + void (*ud_free)(void *); + + void *ud; + + double precision; + + /* state */ + double last_update; /* last value callback function was called with */ + + double start; /* start of sub-progress section */ + double end; /* end of sub-progress section */ +}; + + +void +_zip_progress_end(zip_progress_t *progress) { + _zip_progress_update(progress, 1.0); +} + + +void +_zip_progress_free(zip_progress_t *progress) { + if (progress == NULL) { + return; + } + + if (progress->ud_free) { + progress->ud_free(progress->ud); + } + + free(progress); +} + + +zip_progress_t * +_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { + zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress)); + + if (progress == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + progress->za = za; + progress->callback = callback; + progress->ud_free = ud_free; + progress->ud = ud; + progress->precision = precision; + + return progress; +} + + +void +_zip_progress_start(zip_progress_t *progress) { + if (progress == NULL) { + return; + } + + progress->last_update = 0.0; + progress->callback(progress->za, 0.0, progress->ud); +} + + +void +_zip_progress_subrange(zip_progress_t *progress, double start, double end) { + if (progress == NULL) { + return; + } + + progress->start = start; + progress->end = end; + + _zip_progress_update(progress, 0.0); +} + +void +_zip_progress_update(zip_progress_t *progress, double sub_current) { + double current; + + if (progress == NULL) { + return; + } + + 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; + } +} + + +ZIP_EXTERN int +zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) { + zip_progress_t *progress = NULL; + + if (callback != NULL) { + if ((progress = _zip_progress_new(za, precision, callback, ud_free, ud)) == NULL) { + return -1; + } + } + + _zip_progress_free(za->progress); + za->progress = progress; + + return 0; +} + + +struct legacy_ud { + zip_progress_callback_t callback; +}; + + +static void +_zip_legacy_progress_callback(zip_t *za, double progress, void *vud) { + struct legacy_ud *ud = (struct legacy_ud *)vud; + + ud->callback(progress); +} + +ZIP_EXTERN void +zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback) { + struct legacy_ud *ud; + + if (progress_callback == NULL) { + zip_register_progress_callback_with_state(za, 0, NULL, NULL, NULL); + } + + if ((ud = (struct legacy_ud *)malloc(sizeof(*ud))) == NULL) { + return; + } + + ud->callback = progress_callback; + + if (zip_register_progress_callback_with_state(za, 0.001, _zip_legacy_progress_callback, free, ud) < 0) { + free(ud); + } +} diff --git a/src/Common/libzip/zip_rename.c b/src/Common/libzip/zip_rename.c index 14e101d7..0cc81ed4 100644 --- a/src/Common/libzip/zip_rename.c +++ b/src/Common/libzip/zip_rename.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ ZIP_EXTERN int -zip_rename(zip_t *za, zip_uint64_t idx, const char *name) -{ +zip_rename(zip_t *za, zip_uint64_t idx, const char *name) { return zip_file_rename(za, idx, name, 0); diff --git a/src/Common/libzip/zip_replace.c b/src/Common/libzip/zip_replace.c index eed019a0..34b922e5 100644 --- a/src/Common/libzip/zip_replace.c +++ b/src/Common/libzip/zip_replace.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ ZIP_EXTERN int -zip_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source) -{ +zip_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source) { return zip_file_replace(za, idx, source, 0); diff --git a/src/Common/libzip/zip_set_archive_comment.c b/src/Common/libzip/zip_set_archive_comment.c index 9090eec9..221fde59 100644 --- a/src/Common/libzip/zip_set_archive_comment.c +++ b/src/Common/libzip/zip_set_archive_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN int -zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) -{ +zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) { zip_string_t *cstr; @@ -55,3 +54,3 @@ zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) if (len > 0) { - if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL) + if ((cstr = _zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL) return -1; @@ -70,4 +69,3 @@ zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) - if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr)) - || (za->comment_orig == NULL && cstr == NULL))) { + if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr)) || (za->comment_orig == NULL && cstr == NULL))) { _zip_string_free(cstr); @@ -79,3 +77,3 @@ zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len) } - + return 0; diff --git a/src/Common/libzip/zip_set_archive_flag.c b/src/Common/libzip/zip_set_archive_flag.c index 2625b2e6..6fb11316 100644 --- a/src/Common/libzip/zip_set_archive_flag.c +++ b/src/Common/libzip/zip_set_archive_flag.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,6 +38,5 @@ ZIP_EXTERN int -zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) -{ +zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) { unsigned int new_flags; - + if (value) @@ -55,4 +54,3 @@ zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value) - if ((flag & ZIP_AFL_RDONLY) && value - && (za->ch_flags & ZIP_AFL_RDONLY) == 0) { + if ((flag & ZIP_AFL_RDONLY) && value && (za->ch_flags & ZIP_AFL_RDONLY) == 0) { if (_zip_changed(za, NULL)) { diff --git a/src/Common/libzip/zip_set_default_password.c b/src/Common/libzip/zip_set_default_password.c index ff7e35a6..33c1754d 100644 --- a/src/Common/libzip/zip_set_default_password.c +++ b/src/Common/libzip/zip_set_default_password.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ ZIP_EXTERN int -zip_set_default_password(zip_t *za, const char *passwd) -{ +zip_set_default_password(zip_t *za, const char *passwd) { if (za == NULL) @@ -47,5 +46,5 @@ zip_set_default_password(zip_t *za, const char *passwd) free(za->default_password); - + if (passwd) { - if ((za->default_password=strdup(passwd)) == NULL) { + if ((za->default_password = strdup(passwd)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); diff --git a/src/Common/libzip/zip_set_file_comment.c b/src/Common/libzip/zip_set_file_comment.c index d3566937..93594f0a 100644 --- a/src/Common/libzip/zip_set_file_comment.c +++ b/src/Common/libzip/zip_set_file_comment.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,7 +41,6 @@ ZIP_EXTERN int -zip_set_file_comment(zip_t *za, zip_uint64_t idx, const char *comment, int len) -{ +zip_set_file_comment(zip_t *za, zip_uint64_t idx, const char *comment, int len) { if (len < 0 || len > ZIP_UINT16_MAX) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } diff --git a/src/Common/libzip/zip_set_file_compression.c b/src/Common/libzip/zip_set_file_compression.c index 7bb0bf94..6de2d403 100644 --- a/src/Common/libzip/zip_set_file_compression.c +++ b/src/Common/libzip/zip_set_file_compression.c @@ -2,3 +2,3 @@ zip_set_file_compression.c -- set compression for file in archive - Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ 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; @@ -43,3 +42,3 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui - if (idx >= za->nentry) { + if (idx >= za->nentry || flags > 9) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -53,3 +52,3 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui - if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) { + if (!zip_compression_method_supported(method, true)) { zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); @@ -58,8 +57,11 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui - e = za->entry+idx; - + e = za->entry + idx; + old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method); - - /* TODO: revisit this when flags are supported, since they may require a recompression */ - + + /* TODO: do we want to recompress if level is set? Only if it's + * different than what bit flags tell us, but those are not + * defined for all compression methods, or not directly mappable + * to levels */ + if (method == old_method) { @@ -67,2 +69,3 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; + e->changes->compression_level = 0; if (e->changes->changed == 0) { @@ -74,13 +77,14 @@ zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_ui else { - 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->comp_method = method; - e->changes->changed |= ZIP_DIRENT_COMP_METHOD; + 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->comp_method = method; + e->changes->compression_level = (zip_uint16_t)flags; + e->changes->changed |= ZIP_DIRENT_COMP_METHOD; } - + return 0; diff --git a/src/Common/libzip/zip_set_name.c b/src/Common/libzip/zip_set_name.c index 34b76154..33fb4bc8 100644 --- a/src/Common/libzip/zip_set_name.c +++ b/src/Common/libzip/zip_set_name.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,4 +41,3 @@ int -_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) -{ +_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { zip_entry_t *e; @@ -61,4 +60,4 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) if (name && name[0] != '\0') { - /* TODO: check for string too long */ - if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL) + /* TODO: check for string too long */ + if ((str = _zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL) return -1; @@ -71,3 +70,3 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) /* TODO: encoding flags needed for CP437? */ - if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) { + if ((i = _zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) { _zip_string_free(str); @@ -78,3 +77,3 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) /* no effective name change */ - if (i>=0 && (zip_uint64_t)i == idx) { + if (i >= 0 && (zip_uint64_t)i == idx) { _zip_string_free(str); @@ -83,3 +82,3 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) - e = za->entry+idx; + e = za->entry + idx; @@ -91,3 +90,3 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) if (!same_as_orig && e->changes == NULL) { - if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -112,3 +111,3 @@ _zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags) } - + if (old_str) { diff --git a/src/Common/libzip/zip_source_begin_write.c b/src/Common/libzip/zip_source_begin_write.c index 04593377..0b010df9 100644 --- a/src/Common/libzip/zip_source_begin_write.c +++ b/src/Common/libzip/zip_source_begin_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,11 +38,10 @@ ZIP_EXTERN int -zip_source_begin_write(zip_source_t *src) -{ +zip_source_begin_write(zip_source_t *src) { if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_BEGIN_WRITE) < 0) { - return -1; + return -1; } @@ -50,3 +49,3 @@ zip_source_begin_write(zip_source_t *src) src->write_state = ZIP_SOURCE_WRITE_OPEN; - + return 0; diff --git a/src/Common/libzip/zip_get_compression_implementation.c b/src/Common/libzip/zip_source_begin_write_cloning.c index 5f8d0c7b..8c4cf719 100644 --- a/src/Common/libzip/zip_get_compression_implementation.c +++ b/src/Common/libzip/zip_source_begin_write_cloning.c @@ -1,4 +1,4 @@ /* - zip_get_compression_implementation.c -- get compression implementation - Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner + zip_source_begin_write_cloning.c -- clone part of file for writing + Copyright (C) 2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,8 +37,16 @@ -zip_compression_implementation -_zip_get_compression_implementation(zip_int32_t cm, int operation) -{ - if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm)) - return zip_source_deflate; - return NULL; +ZIP_EXTERN int +zip_source_begin_write_cloning(zip_source_t *src, zip_uint64_t offset) { + if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_source_call(src, NULL, offset, ZIP_SOURCE_BEGIN_WRITE_CLONING) < 0) { + return -1; + } + + src->write_state = ZIP_SOURCE_WRITE_OPEN; + + return 0; } diff --git a/src/Common/libzip/zip_source_buffer.c b/src/Common/libzip/zip_source_buffer.c index f3f8ee0d..05ade4ac 100644 --- a/src/Common/libzip/zip_source_buffer.c +++ b/src/Common/libzip/zip_source_buffer.c @@ -2,3 +2,3 @@ zip_source_buffer.c -- create zip data source from buffer - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,3 +39,3 @@ #ifndef WRITE_FRAGMENT_SIZE -#define WRITE_FRAGMENT_SIZE 64*1024 +#define WRITE_FRAGMENT_SIZE (64 * 1024) #endif @@ -43,10 +43,15 @@ struct buffer { - zip_uint64_t fragment_size; /* size of each fragment */ - - zip_uint8_t **fragments; /* pointers to fragments */ - zip_uint64_t nfragments; /* number of allocated fragments */ - zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */ - zip_uint64_t size; /* size of data in bytes */ - zip_uint64_t offset; /* current offset */ - int free_data; + zip_buffer_fragment_t *fragments; /* fragments */ + zip_uint64_t *fragment_offsets; /* offset of each fragment from start of buffer, nfragments+1 entries */ + zip_uint64_t nfragments; /* number of allocated fragments */ + zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */ + + zip_uint64_t first_owned_fragment; /* first fragment to free data from */ + + zip_uint64_t shared_fragments; /* number of shared fragments */ + struct buffer *shared_buffer; /* buffer fragments are shared with */ + zip_uint64_t size; /* size of buffer */ + + zip_uint64_t offset; /* current offset in buffer */ + zip_uint64_t current_fragment; /* fragment current offset is in */ }; @@ -62,6 +67,10 @@ struct read_data { +#define buffer_capacity(buffer) ((buffer)->fragment_offsets[(buffer)->nfragments]) +#define buffer_size(buffer) ((buffer)->size) + +static buffer_t *buffer_clone(buffer_t *buffer, zip_uint64_t length, zip_error_t *error); +static zip_uint64_t buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset); static void buffer_free(buffer_t *buffer); -static buffer_t *buffer_new(zip_uint64_t fragment_size); -static buffer_t *buffer_new_read(const void *data, zip_uint64_t length, int free_data); -static buffer_t *buffer_new_write(zip_uint64_t fragment_size); +static bool buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error); +static buffer_t *buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int free_data, zip_error_t *error); static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length); @@ -74,4 +83,3 @@ static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t); ZIP_EXTERN zip_source_t * -zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) -{ +zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) { if (za == NULL) @@ -84,8 +92,34 @@ zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep) ZIP_EXTERN zip_source_t * -zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) -{ +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; + } + + fragment.data = (zip_uint8_t *)data; + fragment.length = len; + + return zip_source_buffer_fragment_create(&fragment, 1, freep, error); +} + + +ZIP_EXTERN zip_source_t * +zip_source_buffer_fragment(zip_t *za, const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep) { + if (za == NULL) { + return NULL; + } + + return zip_source_buffer_fragment_create(fragments, nfragments, freep, &za->error); +} + + +ZIP_EXTERN zip_source_t * +zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_error_t *error) { struct read_data *ctx; zip_source_t *zs; + buffer_t *buffer; - if (data == NULL && len > 0) { + if (fragments == NULL && nfragments > 0) { zip_error_set(error, ZIP_ER_INVAL, 0); @@ -94,4 +128,3 @@ zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_erro - if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); + if ((buffer = buffer_new(fragments, nfragments, freep, error)) == NULL) { return NULL; @@ -99,5 +132,5 @@ zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_erro - if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) { + if ((ctx = (struct read_data *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); - free(ctx); + buffer_free(buffer); return NULL; @@ -105,2 +138,3 @@ zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_erro + ctx->in = buffer; ctx->out = NULL; @@ -108,4 +142,4 @@ zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_erro zip_error_init(&ctx->error); - - if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) { + + if ((zs = zip_source_function_create(read_data, ctx, error)) == NULL) { buffer_free(ctx->in); @@ -120,4 +154,3 @@ zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_erro static zip_int64_t -read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) -{ +read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct read_data *ctx = (struct read_data *)state; @@ -125,132 +158,120 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) switch (cmd) { - case ZIP_SOURCE_BEGIN_WRITE: - if ((ctx->out = buffer_new_write(WRITE_FRAGMENT_SIZE)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - return 0; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_COMMIT_WRITE: - buffer_free(ctx->in); - ctx->in = ctx->out; - ctx->out = NULL; - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - buffer_free(ctx->in); - buffer_free(ctx->out); - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - ctx->in->offset = 0; - return 0; - - case ZIP_SOURCE_READ: - if (len > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - return buffer_read(ctx->in, data, len); - - case ZIP_SOURCE_REMOVE: - { - buffer_t *empty = buffer_new_read(NULL, 0, 0); - if (empty == 0) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - - buffer_free(ctx->in); - ctx->in = empty; - return 0; + case ZIP_SOURCE_BEGIN_WRITE: + if ((ctx->out = buffer_new(NULL, 0, 0, &ctx->error)) == NULL) { + return -1; } + ctx->out->offset = 0; + ctx->out->current_fragment = 0; + return 0; - case ZIP_SOURCE_ROLLBACK_WRITE: - buffer_free(ctx->out); - ctx->out = NULL; - return 0; - - case ZIP_SOURCE_SEEK: - return buffer_seek(ctx->in, data, len, &ctx->error); - - case ZIP_SOURCE_SEEK_WRITE: - return buffer_seek(ctx->out, data, len, &ctx->error); - - case ZIP_SOURCE_STAT: - { - zip_stat_t *st; - - if (len < sizeof(*st)) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - st = (zip_stat_t *)data; - - zip_stat_init(st); - st->mtime = ctx->mtime; - st->size = ctx->in->size; - st->comp_size = st->size; - st->comp_method = ZIP_CM_STORE; - st->encryption_method = ZIP_EM_NONE; - st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD; - - return sizeof(*st); + case ZIP_SOURCE_BEGIN_WRITE_CLONING: + if ((ctx->out = buffer_clone(ctx->in, len, &ctx->error)) == NULL) { + return -1; } + ctx->out->offset = len; + ctx->out->current_fragment = ctx->out->nfragments; + return 0; - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1); - - case ZIP_SOURCE_TELL: - if (ctx->in->offset > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); - return -1; - } - return (zip_int64_t)ctx->in->offset; - - - case ZIP_SOURCE_TELL_WRITE: - if (ctx->out->offset > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); - return -1; - } - return (zip_int64_t)ctx->out->offset; + case ZIP_SOURCE_CLOSE: + return 0; - case ZIP_SOURCE_WRITE: - if (len > ZIP_INT64_MAX) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - return buffer_write(ctx->out, data, len, &ctx->error); + case ZIP_SOURCE_COMMIT_WRITE: + buffer_free(ctx->in); + ctx->in = ctx->out; + ctx->out = NULL; + return 0; + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + buffer_free(ctx->in); + buffer_free(ctx->out); + free(ctx); + return 0; - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + case ZIP_SOURCE_OPEN: + ctx->in->offset = 0; + ctx->in->current_fragment = 0; + return 0; + + case ZIP_SOURCE_READ: + if (len > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + return buffer_read(ctx->in, data, len); + + case ZIP_SOURCE_REMOVE: { + buffer_t *empty = buffer_new(NULL, 0, 0, &ctx->error); + if (empty == NULL) { + return -1; + } + + buffer_free(ctx->in); + ctx->in = empty; + return 0; } -} + case ZIP_SOURCE_ROLLBACK_WRITE: + buffer_free(ctx->out); + ctx->out = NULL; + return 0; -static void -buffer_free(buffer_t *buffer) -{ - if (buffer == NULL) { - return; + case ZIP_SOURCE_SEEK: + return buffer_seek(ctx->in, data, len, &ctx->error); + + case ZIP_SOURCE_SEEK_WRITE: + return buffer_seek(ctx->out, data, len, &ctx->error); + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + if (len < sizeof(*st)) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + st = (zip_stat_t *)data; + + zip_stat_init(st); + st->mtime = ctx->mtime; + st->size = ctx->in->size; + st->comp_size = st->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid = ZIP_STAT_MTIME | ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; + + return sizeof(*st); } - if (buffer->free_data) { - zip_uint64_t i; + case ZIP_SOURCE_SUPPORTS: + return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1); + + case ZIP_SOURCE_TELL: + if (ctx->in->offset > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); + return -1; + } + return (zip_int64_t)ctx->in->offset; + - for (i=0; i < buffer->nfragments; i++) { - free(buffer->fragments[i]); + case ZIP_SOURCE_TELL_WRITE: + if (ctx->out->offset > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW); + return -1; } + return (zip_int64_t)ctx->out->offset; + + case ZIP_SOURCE_WRITE: + if (len > ZIP_INT64_MAX) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + return buffer_write(ctx->out, data, len, &ctx->error); + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } - free(buffer->fragments); - free(buffer); } @@ -259,28 +280,34 @@ buffer_free(buffer_t *buffer) static buffer_t * -buffer_new(zip_uint64_t fragment_size) -{ - buffer_t *buffer; +buffer_clone(buffer_t *buffer, zip_uint64_t offset, zip_error_t *error) { + zip_uint64_t fragment, fragment_offset, waste; + buffer_t *clone; - if ((buffer = malloc(sizeof(*buffer))) == NULL) { - return NULL; + if (offset == 0) { + return buffer_new(NULL, 0, 1, error); } - buffer->fragment_size = fragment_size; - buffer->offset = 0; - buffer->free_data = 0; - buffer->nfragments = 0; - buffer->fragments_capacity = 0; - buffer->fragments = NULL; - buffer->size = 0; + if (offset > buffer->size) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + if (buffer->shared_buffer != NULL) { + zip_error_set(error, ZIP_ER_INUSE, 0); + return NULL; + } - return buffer; -} + fragment = buffer_find_fragment(buffer, offset); + fragment_offset = offset - buffer->fragment_offsets[fragment]; + if (fragment_offset == 0) { + fragment--; + fragment_offset = buffer->fragments[fragment].length; + } -static buffer_t * -buffer_new_read(const void *data, zip_uint64_t length, int free_data) -{ - buffer_t *buffer; + waste = buffer->fragments[fragment].length - fragment_offset; + if (waste > offset) { + zip_error_set(error, ZIP_ER_OPNOTSUPP, 0); + return NULL; + } - if ((buffer = buffer_new(length)) == NULL) { + if ((clone = buffer_new(buffer->fragments, fragment + 1, 0, error)) == NULL) { return NULL; @@ -288,17 +315,90 @@ buffer_new_read(const void *data, zip_uint64_t length, int free_data) - buffer->size = length; +#ifndef __clang_analyzer__ + /* clone->fragments can't be null, since it was created with at least one fragment */ + clone->fragments[clone->nfragments - 1].length = fragment_offset; +#endif + clone->fragment_offsets[clone->nfragments] = offset; + clone->size = offset; - if (length > 0) { - if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) { - buffer_free(buffer); - return NULL; + clone->first_owned_fragment = ZIP_MIN(buffer->first_owned_fragment, clone->nfragments - 1); + + buffer->shared_buffer = clone; + clone->shared_buffer = buffer; + buffer->shared_fragments = clone->nfragments; + clone->shared_fragments = fragment + 1; + + return clone; +} + + +static zip_uint64_t +buffer_find_fragment(const buffer_t *buffer, zip_uint64_t offset) { + zip_uint64_t low, high, mid; + + low = 0; + high = buffer->nfragments - 1; + + while (low < high) { + mid = (high - low) / 2 + low; + if (buffer->fragment_offsets[mid] > offset) { + high = mid - 1; + } + else if (mid == buffer->nfragments || buffer->fragment_offsets[mid + 1] > offset) { + return mid; + } + else { + low = mid + 1; } - buffer->fragments_capacity = 1; + } + + return low; +} - buffer->nfragments = 1; - buffer->fragments[0] = (zip_uint8_t *)data; - buffer->free_data = free_data; + +static void +buffer_free(buffer_t *buffer) { + zip_uint64_t i; + + if (buffer == NULL) { + return; } - return buffer; + if (buffer->shared_buffer != NULL) { + buffer->shared_buffer->shared_buffer = NULL; + buffer->shared_buffer->shared_fragments = 0; + + buffer->first_owned_fragment = ZIP_MAX(buffer->first_owned_fragment, buffer->shared_fragments); + } + + for (i = buffer->first_owned_fragment; i < buffer->nfragments; i++) { + free(buffer->fragments[i].data); + } + free(buffer->fragments); + free(buffer->fragment_offsets); + free(buffer); +} + + +static bool +buffer_grow_fragments(buffer_t *buffer, zip_uint64_t capacity, zip_error_t *error) { + zip_buffer_fragment_t *fragments; + zip_uint64_t *offsets; + + if (capacity < buffer->fragments_capacity) { + return true; + } + + if ((fragments = realloc(buffer->fragments, sizeof(buffer->fragments[0]) * capacity)) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; + } + buffer->fragments = fragments; + if ((offsets = realloc(buffer->fragment_offsets, sizeof(buffer->fragment_offsets[0]) * (capacity + 1))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return false; + } + buffer->fragment_offsets = offsets; + buffer->fragments_capacity = capacity; + + return true; } @@ -307,7 +407,6 @@ buffer_new_read(const void *data, zip_uint64_t length, int free_data) static buffer_t * -buffer_new_write(zip_uint64_t fragment_size) -{ +buffer_new(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int free_data, zip_error_t *error) { buffer_t *buffer; - if ((buffer = buffer_new(fragment_size)) == NULL) { + if ((buffer = malloc(sizeof(*buffer))) == NULL) { return NULL; @@ -315,9 +414,50 @@ buffer_new_write(zip_uint64_t fragment_size) - if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) { - buffer_free(buffer); - return NULL; - } - buffer->fragments_capacity = 1; + buffer->offset = 0; + buffer->first_owned_fragment = 0; + buffer->size = 0; + buffer->fragments = NULL; + buffer->fragment_offsets = NULL; buffer->nfragments = 0; - buffer->free_data = 1; + buffer->fragments_capacity = 0; + buffer->shared_buffer = NULL; + buffer->shared_fragments = 0; + + if (nfragments == 0) { + if ((buffer->fragment_offsets = malloc(sizeof(buffer->fragment_offsets[0]))) == NULL) { + free(buffer); + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + buffer->fragment_offsets[0] = 0; + } + else { + zip_uint64_t i, j, offset; + + if (!buffer_grow_fragments(buffer, nfragments, NULL)) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + buffer_free(buffer); + return NULL; + } + + offset = 0; + for (i = 0, j = 0; i < nfragments; i++) { + if (fragments[i].length == 0) { + continue; + } + if (fragments[i].data == NULL) { + zip_error_set(error, ZIP_ER_INVAL, 0); + buffer_free(buffer); + return NULL; + } + buffer->fragments[j].data = fragments[i].data; + buffer->fragments[j].length = fragments[i].length; + buffer->fragment_offsets[i] = offset; + offset += fragments[i].length; + j++; + } + buffer->nfragments = j; + buffer->first_owned_fragment = free_data ? 0 : buffer->nfragments; + buffer->fragment_offsets[nfragments] = offset; + buffer->size = offset; + } @@ -326,6 +466,4 @@ buffer_new_write(zip_uint64_t fragment_size) - static zip_int64_t -buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) -{ +buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) { zip_uint64_t n, i, fragment_offset; @@ -341,12 +479,14 @@ buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) - i = buffer->offset / buffer->fragment_size; - fragment_offset = buffer->offset % buffer->fragment_size; + i = buffer->current_fragment; + fragment_offset = buffer->offset - buffer->fragment_offsets[i]; n = 0; while (n < length) { - zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset); - - memcpy(data + n, buffer->fragments[i] + fragment_offset, left); + zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); + memcpy(data + n, buffer->fragments[i].data + fragment_offset, left); + + if (left == buffer->fragments[i].length - fragment_offset) { + i++; + } n += left; - i++; fragment_offset = 0; @@ -355,2 +495,3 @@ buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) buffer->offset += n; + buffer->current_fragment = i; return (zip_int64_t)n; @@ -360,11 +501,11 @@ buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) static int -buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) -{ +buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) { zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error); - + if (new_offset < 0) { - return -1; + return -1; } - + buffer->offset = (zip_uint64_t)new_offset; + buffer->current_fragment = buffer_find_fragment(buffer, buffer->offset); return 0; @@ -374,8 +515,6 @@ buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error) static zip_int64_t -buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) -{ - zip_uint64_t n, i, fragment_offset; - zip_uint8_t **fragments; +buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) { + zip_uint64_t n, i, fragment_offset, capacity; - if (buffer->offset + length + buffer->fragment_size - 1 < length) { + if (buffer->offset + length + WRITE_FRAGMENT_SIZE - 1 < length) { zip_error_set(error, ZIP_ER_INVAL, 0); @@ -385,5 +524,6 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip /* grow buffer if needed */ - if (buffer->offset + length > buffer->nfragments * buffer->fragment_size) { - zip_uint64_t needed_fragments = (buffer->offset + length + buffer->fragment_size - 1) / buffer->fragment_size; - + capacity = buffer_capacity(buffer); + if (buffer->offset + length > capacity) { + zip_uint64_t needed_fragments = buffer->nfragments + (length - (capacity - buffer->offset) + WRITE_FRAGMENT_SIZE - 1) / WRITE_FRAGMENT_SIZE; + if (needed_fragments > buffer->fragments_capacity) { @@ -391,2 +531,5 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip + if (new_capacity == 0) { + new_capacity = 16; + } while (new_capacity < needed_fragments) { @@ -395,5 +538,3 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip - fragments = realloc(buffer->fragments, new_capacity * sizeof(*fragments)); - - if (fragments == NULL) { + if (!buffer_grow_fragments(buffer, new_capacity, error)) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -401,5 +542,2 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip } - - buffer->fragments = fragments; - buffer->fragments_capacity = new_capacity; } @@ -407,3 +545,3 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip while (buffer->nfragments < needed_fragments) { - if ((buffer->fragments[buffer->nfragments] = malloc(buffer->fragment_size)) == NULL) { + if ((buffer->fragments[buffer->nfragments].data = malloc(WRITE_FRAGMENT_SIZE)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -411,3 +549,6 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip } + buffer->fragments[buffer->nfragments].length = WRITE_FRAGMENT_SIZE; buffer->nfragments++; + capacity += WRITE_FRAGMENT_SIZE; + buffer->fragment_offsets[buffer->nfragments] = capacity; } @@ -415,12 +556,14 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip - i = buffer->offset / buffer->fragment_size; - fragment_offset = buffer->offset % buffer->fragment_size; + i = buffer->current_fragment; + fragment_offset = buffer->offset - buffer->fragment_offsets[i]; n = 0; while (n < length) { - zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset); - - memcpy(buffer->fragments[i] + fragment_offset, data + n, left); + zip_uint64_t left = ZIP_MIN(length - n, buffer->fragments[i].length - fragment_offset); + memcpy(buffer->fragments[i].data + fragment_offset, data + n, left); + + if (n == buffer->fragments[i].length - fragment_offset) { + i++; + } n += left; - i++; fragment_offset = 0; @@ -429,2 +572,3 @@ buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip buffer->offset += n; + buffer->current_fragment = i; if (buffer->offset > buffer->size) { diff --git a/src/Common/libzip/zip_source_call.c b/src/Common/libzip/zip_source_call.c index 21f28bc4..ec54b92e 100644 --- a/src/Common/libzip/zip_source_call.c +++ b/src/Common/libzip/zip_source_call.c @@ -3,6 +3,6 @@ Copyright (C) 2009-2014 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 @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ zip_int64_t -_zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) -{ +_zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) { zip_int64_t ret; - + if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(command)) == 0) { - zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } @@ -48,19 +47,19 @@ _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_ if (src->src == NULL) { - ret = src->cb.f(src->ud, data, length, command); + ret = src->cb.f(src->ud, data, length, command); } else { - ret = src->cb.l(src->src, src->ud, data, length, command); + ret = src->cb.l(src->src, src->ud, data, length, command); } - + if (ret < 0) { - if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) { - int e[2]; - - if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { - zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); - } - else { - zip_error_set(&src->error, e[0], e[1]); - } - } + if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) { + int e[2]; + + if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { + zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); + } + else { + zip_error_set(&src->error, e[0], e[1]); + } + } } diff --git a/src/Common/libzip/zip_source_close.c b/src/Common/libzip/zip_source_close.c index 36bc8423..cbc3bea8 100644 --- a/src/Common/libzip/zip_source_close.c +++ b/src/Common/libzip/zip_source_close.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ int -zip_source_close(zip_source_t *src) -{ +zip_source_close(zip_source_t *src) { if (!ZIP_SOURCE_IS_OPEN_READING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + src->open_count--; diff --git a/src/Common/libzip/zip_source_commit_write.c b/src/Common/libzip/zip_source_commit_write.c index ba77abc3..26c3dd7a 100644 --- a/src/Common/libzip/zip_source_commit_write.c +++ b/src/Common/libzip/zip_source_commit_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ ZIP_EXTERN int -zip_source_commit_write(zip_source_t *src) -{ +zip_source_commit_write(zip_source_t *src) { if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + if (src->open_count > 1) { @@ -50,3 +49,3 @@ zip_source_commit_write(zip_source_t *src) else if (ZIP_SOURCE_IS_OPEN_READING(src)) { - if (zip_source_close(src) < 0) { + if (zip_source_close(src) < 0) { return -1; @@ -54,10 +53,10 @@ zip_source_commit_write(zip_source_t *src) } - + if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_COMMIT_WRITE) < 0) { - src->write_state = ZIP_SOURCE_WRITE_FAILED; - return -1; + src->write_state = ZIP_SOURCE_WRITE_FAILED; + return -1; } - + src->write_state = ZIP_SOURCE_WRITE_CLOSED; - + return 0; diff --git a/src/Common/libzip/zip_source_compress.c b/src/Common/libzip/zip_source_compress.c new file mode 100644 index 00000000..a1ac3e03 --- /dev/null +++ b/src/Common/libzip/zip_source_compress.c @@ -0,0 +1,367 @@ +/* + zip_source_compress.c -- (de)compression routines + Copyright (C) 2017 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 <limits.h> +#include <stdlib.h> +#include <string.h> + +#include "zipint.h" + +struct context { + zip_error_t error; + + bool end_of_input; + bool end_of_stream; + bool can_store; + bool is_stored; /* only valid if end_of_stream is true */ + bool compress; + zip_int32_t method; + + zip_uint64_t size; + zip_int64_t first_read; + zip_uint8_t buffer[BUFSIZE]; + + zip_compression_algorithm_t *algorithm; + void *ud; +}; + + +struct implementation { + zip_uint16_t method; + zip_compression_algorithm_t *compress; + zip_compression_algorithm_t *decompress; +}; + +static struct implementation implementations[] = { + {ZIP_CM_DEFLATE, &zip_algorithm_deflate_compress, &zip_algorithm_deflate_decompress}, +#if defined(HAVE_LIBBZ2) + {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress}, +#endif +}; + +static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]); + +static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags); +static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); +static void context_free(struct context *ctx); +static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm); +static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t); + +static zip_compression_algorithm_t * +get_algorithm(zip_int32_t method, bool compress) { + size_t i; + zip_uint16_t real_method = ZIP_CM_ACTUAL(method); + + for (i = 0; i < implementations_size; i++) { + if (implementations[i].method == real_method) { + if (compress) { + return implementations[i].compress; + } + else { + return implementations[i].decompress; + } + } + } + + return NULL; +} + +bool +zip_compression_method_supported(zip_int32_t method, bool compress) { + if (method == ZIP_CM_STORE) { + return true; + } + return get_algorithm(method, compress) != NULL; +} + +zip_source_t * +zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, int compression_flags) { + return compression_source_new(za, src, method, true, compression_flags); +} + +zip_source_t * +zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) { + return compression_source_new(za, src, method, false, 0); +} + + +static zip_source_t * +compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags) { + struct context *ctx; + zip_source_t *s2; + zip_compression_algorithm_t *algorithm = NULL; + + if (src == NULL) { + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((algorithm = get_algorithm(method, compress)) == NULL) { + zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return NULL; + } + + if ((ctx = context_new(method, compress, compression_flags, algorithm)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((s2 = zip_source_layered(za, src, compress_callback, ctx)) == NULL) { + context_free(ctx); + return NULL; + } + + return s2; +} + + +static struct context * +context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm) { + struct context *ctx; + + if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) { + return NULL; + } + zip_error_init(&ctx->error); + ctx->can_store = compress ? ZIP_CM_IS_DEFAULT(method) : false; + ctx->algorithm = algorithm; + ctx->method = method; + ctx->compress = compress; + ctx->end_of_input = false; + ctx->end_of_stream = false; + ctx->is_stored = false; + + if ((ctx->ud = ctx->algorithm->allocate(ZIP_CM_ACTUAL(method), compression_flags, &ctx->error)) == NULL) { + zip_error_fini(&ctx->error); + free(ctx); + return NULL; + } + + return ctx; +} + + +static void +context_free(struct context *ctx) { + if (ctx == NULL) { + return; + } + + ctx->algorithm->deallocate(ctx->ud); + zip_error_fini(&ctx->error); + + free(ctx); +} + + +static zip_int64_t +compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t len) { + zip_compression_status_t ret; + bool end; + zip_int64_t n; + zip_uint64_t out_offset; + zip_uint64_t out_len; + + if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK) { + return -1; + } + + if (len == 0 || ctx->end_of_stream) { + return 0; + } + + out_offset = 0; + + end = false; + while (!end && out_offset < len) { + out_len = len - out_offset; + ret = ctx->algorithm->process(ctx->ud, (zip_uint8_t *)data + out_offset, &out_len); + + if (ret != ZIP_COMPRESSION_ERROR) { + out_offset += out_len; + } + + switch (ret) { + case ZIP_COMPRESSION_END: + ctx->end_of_stream = true; + + if (!ctx->end_of_input) { + /* TODO: garbage after stream, or compression ended before all data read */ + } + + if (ctx->first_read < 0) { + /* we got end of processed stream before reading any input data */ + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + end = true; + break; + } + if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) { + ctx->is_stored = true; + ctx->size = (zip_uint64_t)ctx->first_read; + memcpy(data, ctx->buffer, ctx->size); + return (zip_int64_t)ctx->size; + } + end = true; + break; + + case ZIP_COMPRESSION_OK: + break; + + case ZIP_COMPRESSION_NEED_DATA: + if (ctx->end_of_input) { + /* TODO: error: stream not ended, but no more input */ + end = true; + break; + } + + if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { + _zip_error_set_from_source(&ctx->error, src); + end = true; + break; + } + else if (n == 0) { + ctx->end_of_input = true; + ctx->algorithm->end_of_input(ctx->ud); + if (ctx->first_read < 0) { + ctx->first_read = 0; + } + } + else { + if (ctx->first_read >= 0) { + /* we overwrote a previously filled ctx->buffer */ + ctx->can_store = false; + } + else { + ctx->first_read = n; + } + + ctx->algorithm->input(ctx->ud, ctx->buffer, (zip_uint64_t)n); + } + break; + + case ZIP_COMPRESSION_ERROR: + /* error set by algorithm */ + if (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) { + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + } + end = true; + break; + } + } + + if (out_offset > 0) { + ctx->can_store = false; + ctx->size += out_offset; + return (zip_int64_t)out_offset; + } + + return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1; +} + + +static zip_int64_t +compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { + struct context *ctx; + + ctx = (struct context *)ud; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + ctx->size = 0; + ctx->end_of_input = false; + ctx->end_of_stream = false; + ctx->is_stored = false; + ctx->first_read = -1; + + if (!ctx->algorithm->start(ctx->ud)) { + return -1; + } + + return 0; + + case ZIP_SOURCE_READ: + return compress_read(src, ctx, data, len); + + case ZIP_SOURCE_CLOSE: + if (!ctx->algorithm->end(ctx->ud)) { + return -1; + } + return 0; + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + st = (zip_stat_t *)data; + + if (ctx->compress) { + if (ctx->end_of_stream) { + st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_ACTUAL(ctx->method); + st->comp_size = ctx->size; + st->valid |= ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD; + } + else { + st->valid &= ~(ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD); + } + } + else { + st->comp_method = ZIP_CM_STORE; + st->valid |= ZIP_STAT_COMP_METHOD; + if (ctx->end_of_stream) { + st->size = ctx->size; + st->valid |= ZIP_STAT_SIZE; + } + else { + st->valid &= ~ZIP_STAT_SIZE; + } + } + } + return 0; + + case ZIP_SOURCE_GET_COMPRESSION_FLAGS: + return ctx->is_stored ? 0 : ctx->algorithm->compression_flags(ctx->ud); + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + context_free(ctx); + return 0; + + case ZIP_SOURCE_SUPPORTS: + return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1); + + default: + zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0); + return -1; + } +} diff --git a/src/Common/libzip/zip_source_crc.c b/src/Common/libzip/zip_source_crc.c index 01f526c6..8797dfe1 100644 --- a/src/Common/libzip/zip_source_crc.c +++ b/src/Common/libzip/zip_source_crc.c @@ -2,3 +2,3 @@ zip_source_crc.c -- pass-through source that calculates CRC32 and size - Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -34,5 +34,5 @@ +#include <limits.h> #include <stdlib.h> #include <string.h> -#include <limits.h> @@ -41,3 +41,3 @@ struct crc_context { - int validate; /* whether to check CRC on EOF and return error on mismatch */ + int validate; /* whether to check CRC on EOF and return error on mismatch */ int crc_complete; /* whether CRC was computed for complete file */ @@ -45,3 +45,3 @@ struct crc_context { zip_uint64_t size; - zip_uint64_t position; /* current reading position */ + zip_uint64_t position; /* current reading position */ zip_uint64_t crc_position; /* how far we've computed the CRC */ @@ -54,4 +54,3 @@ static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_so zip_source_t * -zip_source_crc(zip_t *za, zip_source_t *src, int validate) -{ +zip_source_crc(zip_t *za, zip_source_t *src, int validate) { struct crc_context *ctx; @@ -63,3 +62,3 @@ zip_source_crc(zip_t *za, zip_source_t *src, int validate) - if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) { + if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -80,4 +79,3 @@ zip_source_crc(zip_t *za, zip_source_t *src, int validate) static zip_int64_t -crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) -{ +crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct crc_context *ctx; @@ -88,114 +86,112 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source switch (cmd) { - case ZIP_SOURCE_OPEN: - ctx->position = 0; - return 0; - - case ZIP_SOURCE_READ: - if ((n = zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - if (n == 0) { - if (ctx->crc_position == ctx->position) { - ctx->crc_complete = 1; - ctx->size = ctx->position; - - if (ctx->validate) { - struct zip_stat st; - - if (zip_source_stat(src, &st) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) { - zip_error_set(&ctx->error, ZIP_ER_CRC, 0); - return -1; - } - if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) { - zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); - return -1; - } - } - } - } - else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) { - zip_uint64_t i, nn; - - for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) { - nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n-i); - - ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data+i, (uInt)nn); - ctx->crc_position += nn; + case ZIP_SOURCE_OPEN: + ctx->position = 0; + return 0; + + case ZIP_SOURCE_READ: + if ((n = zip_source_read(src, data, len)) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + if (n == 0) { + if (ctx->crc_position == ctx->position) { + ctx->crc_complete = 1; + ctx->size = ctx->position; + + if (ctx->validate) { + struct zip_stat st; + + if (zip_source_stat(src, &st) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) { + zip_error_set(&ctx->error, ZIP_ER_CRC, 0); + return -1; + } + if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) { + zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); + return -1; + } } - } - ctx->position += (zip_uint64_t)n; - return n; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: - { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - if (ctx->crc_complete) { - /* TODO: Set comp_size, comp_method, encryption_method? - After all, this only works for uncompressed data. */ - st->size = ctx->size; - st->crc = ctx->crc; - st->comp_size = ctx->size; - st->comp_method = ZIP_CM_STORE; - st->encryption_method = ZIP_EM_NONE; - st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;; } - return 0; - } - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx); - return 0; - - case ZIP_SOURCE_SUPPORTS: - { - zip_int64_t mask = zip_source_supports(src); - - if (mask < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1); - } - - case ZIP_SOURCE_SEEK: - { - zip_int64_t new_position; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - - if (args == NULL) { - return -1; + } + else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) { + zip_uint64_t i, nn; + + for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) { + nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n - i); + + ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data + i, (uInt)nn); + ctx->crc_position += nn; } - if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - ctx->position = (zip_uint64_t)new_position; - - return 0; - } - - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->position; - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + } + ctx->position += (zip_uint64_t)n; + return n; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + st = (zip_stat_t *)data; + + if (ctx->crc_complete) { + /* TODO: Set comp_size, comp_method, encryption_method? + After all, this only works for uncompressed data. */ + st->size = ctx->size; + st->crc = ctx->crc; + st->comp_size = ctx->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; + ; + } + return 0; + } + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + free(ctx); + return 0; + + case ZIP_SOURCE_SUPPORTS: { + zip_int64_t mask = zip_source_supports(src); + + if (mask < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1); + } + + case ZIP_SOURCE_SEEK: { + zip_int64_t new_position; + zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + + if (args == NULL) { + return -1; + } + if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + ctx->position = (zip_uint64_t)new_position; + + return 0; + } + + case ZIP_SOURCE_TELL: + return (zip_int64_t)ctx->position; + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } diff --git a/src/Common/libzip/zip_source_error.c b/src/Common/libzip/zip_source_error.c index 91e2dd64..51451698 100644 --- a/src/Common/libzip/zip_source_error.c +++ b/src/Common/libzip/zip_source_error.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ zip_error_t * -zip_source_error(zip_source_t *src) -{ +zip_source_error(zip_source_t *src) { return &src->error; @@ -44,4 +43,3 @@ zip_source_error(zip_source_t *src) bool -_zip_source_had_error(zip_source_t *src) -{ +_zip_source_had_error(zip_source_t *src) { return zip_source_error(src)->zip_err != ZIP_ER_OK; diff --git a/src/Common/libzip/zip_source_file.c b/src/Common/libzip/zip_source_file.c index 6a10c010..77376f44 100644 --- a/src/Common/libzip/zip_source_file.c +++ b/src/Common/libzip/zip_source_file.c @@ -44,4 +44,3 @@ ZIP_EXTERN zip_source_t * -zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) -{ +zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -54,4 +53,3 @@ zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t le ZIP_EXTERN zip_source_t * -zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { if (fname == NULL || length < -1) { diff --git a/src/Common/libzip/zip_source_filep.c b/src/Common/libzip/zip_source_filep.c index a8a271a8..9fc9a01c 100644 --- a/src/Common/libzip/zip_source_filep.c +++ b/src/Common/libzip/zip_source_filep.c @@ -2,3 +2,3 @@ zip_source_filep.c -- create data source from FILE * - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -33,3 +33,2 @@ -#include <sys/stat.h> #include <stdio.h> @@ -37,2 +36,3 @@ #include <string.h> +#include <sys/stat.h> @@ -44,2 +44,13 @@ +#ifdef HAVE_CLONEFILE +#include <sys/attr.h> +#include <sys/clonefile.h> +#define CAN_CLONE +#endif +#ifdef HAVE_FICLONERANGE +#include <linux/fs.h> +#include <sys/ioctl.h> +#define CAN_CLONE +#endif + #ifdef _WIN32 @@ -51,3 +62,3 @@ #ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) #endif @@ -67,3 +78,3 @@ typedef int mode_t; struct read_file { - zip_error_t error; /* last error information */ + zip_error_t error; /* last error information */ zip_int64_t supports; @@ -86,2 +97,5 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_sour 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 int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error); @@ -91,4 +105,3 @@ static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *erro ZIP_EXTERN zip_source_t * -zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) -{ +zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -101,4 +114,3 @@ zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len) ZIP_EXTERN zip_source_t * -zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { if (file == NULL || length < -1) { @@ -113,6 +125,7 @@ zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_ zip_source_t * -_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error) -{ +_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error) { struct read_file *ctx; zip_source_t *zs; + struct stat sb; + bool stat_valid; @@ -132,3 +145,3 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int - if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) { + if ((ctx = (struct read_file *)malloc(sizeof(struct read_file))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -139,3 +152,3 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int if (fname) { - if ((ctx->fname=strdup(fname)) == NULL) { + if ((ctx->fname = strdup(fname)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -150,4 +163,4 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int memcpy(&ctx->st, st, sizeof(ctx->st)); - ctx->st.name = NULL; - ctx->st.valid &= ~ZIP_STAT_NAME; + ctx->st.name = NULL; + ctx->st.valid &= ~ZIP_STAT_NAME; } @@ -172,5 +185,5 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int if (ctx->fname) { - struct stat sb; - if (stat(ctx->fname, &sb) < 0) { - zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno); + stat_valid = stat(ctx->fname, &sb) >= 0; + + if (!stat_valid) { if (ctx->start == 0 && ctx->end == 0) { @@ -179,24 +192,31 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int } - else { - if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) { - ctx->st.mtime = sb.st_mtime; - ctx->st.valid |= ZIP_STAT_MTIME; + } + else { + stat_valid = fstat(fileno(ctx->f), &sb) >= 0; + } + + if (!stat_valid) { + zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno); + } + else { + if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) { + ctx->st.mtime = sb.st_mtime; + ctx->st.valid |= ZIP_STAT_MTIME; + } + if (S_ISREG(sb.st_mode)) { + ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; + + if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) { + zip_error_set(error, ZIP_ER_INVAL, 0); + free(ctx->fname); + free(ctx); + return NULL; } - if (S_ISREG(sb.st_mode)) { - ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; - - if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) { - zip_error_set(error, ZIP_ER_INVAL, 0); - free(ctx->fname); - free(ctx); - return NULL; - } - if (ctx->end == 0) { - ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start; - ctx->st.valid |= ZIP_STAT_SIZE; + if (ctx->end == 0) { + ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start; + ctx->st.valid |= ZIP_STAT_SIZE; - if (start == 0) { - ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; - } + if (ctx->fname && start == 0) { + ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; } @@ -205,7 +225,10 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int } - else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) { - ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; + +#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); } +#endif - if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) { + if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) { free(ctx->fname); @@ -220,4 +243,3 @@ _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int static int -create_temp_output(struct read_file *ctx) -{ +create_temp_output(struct read_file *ctx) { char *temp; @@ -227,3 +249,3 @@ create_temp_output(struct read_file *ctx) - if ((temp=(char *)malloc(strlen(ctx->fname)+8)) == NULL) { + if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); @@ -234,7 +256,7 @@ create_temp_output(struct read_file *ctx) mask = umask(_SAFE_MASK); - if ((tfd=mkstemp(temp)) == -1) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + if ((tfd = mkstemp(temp)) == -1) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); umask(mask); - free(temp); - return -1; + free(temp); + return -1; } @@ -242,8 +264,8 @@ create_temp_output(struct read_file *ctx) - if ((tfp=fdopen(tfd, "r+b")) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); - close(tfd); - (void)remove(temp); - free(temp); - return -1; + if ((tfp = fdopen(tfd, "r+b")) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + close(tfd); + (void)remove(temp); + free(temp); + return -1; } @@ -255,3 +277,3 @@ create_temp_output(struct read_file *ctx) */ - _setmode(_fileno(tfp), _O_BINARY ); + _setmode(_fileno(tfp), _O_BINARY); #endif @@ -264,6 +286,104 @@ create_temp_output(struct read_file *ctx) +#ifdef CAN_CLONE +zip_int64_t static create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset) { + char *temp; + FILE *tfp; + + if (offset > ZIP_OFF_MAX) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, E2BIG); + return -1; + } + + if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); + return -1; + } + sprintf(temp, "%s.XXXXXX", ctx->fname); + +#ifdef HAVE_CLONEFILE +#ifndef __clang_analyzer__ + /* we can't use mkstemp, since clonefile insists on creating the file */ + if (mktemp(temp) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } +#endif + + if (clonefile(ctx->fname, temp, 0) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } + if ((tfp = fopen(temp, "r+b")) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)remove(temp); + free(temp); + return -1; + } +#else + { + int fd; + struct file_clone_range range; + struct stat st; + + if (fstat(fileno(ctx->f), &st) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + return -1; + } + + if ((fd = mkstemp(temp)) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + free(temp); + return -1; + } + + range.src_fd = fileno(ctx->f); + range.src_offset = 0; + range.src_length = ((offset + st.st_blksize - 1) / st.st_blksize) * st.st_blksize; + if (range.src_length > st.st_size) { + range.src_length = 0; + } + range.dest_offset = 0; + if (ioctl(fd, FICLONERANGE, &range) < 0) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)close(fd); + (void)remove(temp); + free(temp); + return -1; + } + + if ((tfp = fdopen(fd, "r+b")) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + (void)close(fd); + (void)remove(temp); + free(temp); + return -1; + } + } +#endif + + if (ftruncate(fileno(tfp), (off_t)offset) < 0) { + (void)fclose(tfp); + (void)remove(temp); + free(temp); + return -1; + } + if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) { + (void)fclose(tfp); + (void)remove(temp); + free(temp); + zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); + } + + ctx->fout = tfp; + ctx->tmpname = temp; + + return 0; +} +#endif + static zip_int64_t -read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) -{ +read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct read_file *ctx; @@ -277,224 +397,230 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) switch (cmd) { - case ZIP_SOURCE_BEGIN_WRITE: - if (ctx->fname == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; - } - return create_temp_output(ctx); - - case ZIP_SOURCE_COMMIT_WRITE: { - mode_t mask; - - if (fclose(ctx->fout) < 0) { - ctx->fout = NULL; - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - } - ctx->fout = NULL; - if (rename(ctx->tmpname, ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); - return -1; - } - mask = umask(022); - umask(mask); - /* not much we can do if chmod fails except make the whole commit fail */ - (void)chmod(ctx->fname, 0666&~mask); - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; + case ZIP_SOURCE_BEGIN_WRITE: + if (ctx->fname == NULL) { + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + return create_temp_output(ctx); + +#ifdef CAN_CLONE + case ZIP_SOURCE_BEGIN_WRITE_CLONING: + if (ctx->fname == NULL) { + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; + } + return create_temp_output_cloning(ctx, len); +#endif + + case ZIP_SOURCE_COMMIT_WRITE: { + mode_t mask; + + if (fclose(ctx->fout) < 0) { + ctx->fout = NULL; + zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); + } + ctx->fout = NULL; + if (rename(ctx->tmpname, ctx->fname) < 0) { + zip_error_set(&ctx->error, ZIP_ER_RENAME, errno); + return -1; + } + mask = umask(022); + umask(mask); + /* not much we can do if chmod fails except make the whole commit fail */ + (void)chmod(ctx->fname, 0666 & ~mask); + 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); + + case ZIP_SOURCE_FREE: + free(ctx->fname); + free(ctx->tmpname); + if (ctx->f) + fclose(ctx->f); + free(ctx); + return 0; + + case ZIP_SOURCE_OPEN: + if (ctx->fname) { + if ((ctx->f = fopen(ctx->fname, "rb")) == NULL) { + zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); + return -1; + } } - 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); - - case ZIP_SOURCE_FREE: - free(ctx->fname); - free(ctx->tmpname); - if (ctx->f) - fclose(ctx->f); - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - if (ctx->fname) { - if ((ctx->f=fopen(ctx->fname, "rb")) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_OPEN, errno); - return -1; - } - } - - if (ctx->start > 0) { - if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) { - /* TODO: skip by reading */ - return -1; - } - } - ctx->current = 0; - return 0; - - case ZIP_SOURCE_READ: - if (ctx->end > 0) { - n = ctx->end - ctx->current; - if (n > len) { - n = len; - } - } - else { - n = len; - } - - if (n > SIZE_MAX) - n = SIZE_MAX; - - if ((i=fread(buf, 1, (size_t)n, ctx->f)) == 0) { - if (ferror(ctx->f)) { - zip_error_set(&ctx->error, ZIP_ER_READ, errno); - return -1; - } - } - ctx->current += i; - - return (zip_int64_t)i; - - case ZIP_SOURCE_REMOVE: - if (remove(ctx->fname) < 0) { - zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno); - return -1; - } - return 0; - - case ZIP_SOURCE_ROLLBACK_WRITE: - if (ctx->fout) { - fclose(ctx->fout); - ctx->fout = NULL; - } - (void)remove(ctx->tmpname); - free(ctx->tmpname); - ctx->tmpname = NULL; - return 0; - - case ZIP_SOURCE_SEEK: { - zip_int64_t new_current; - int need_seek; - zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - - if (args == NULL) + if (ctx->start > 0) { + if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) { + /* TODO: skip by reading */ return -1; + } + } + ctx->current = 0; + return 0; + + case ZIP_SOURCE_READ: + if (ctx->end > 0) { + n = ctx->end - ctx->current; + if (n > len) { + n = len; + } + } + else { + n = len; + } + + if (n > SIZE_MAX) + n = SIZE_MAX; - need_seek = 1; - - switch (args->whence) { - case SEEK_SET: - new_current = args->offset; - break; - - case SEEK_END: - if (ctx->end == 0) { - if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) { - return -1; - } - if ((new_current = ftello(ctx->f)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); - return -1; - } - new_current -= (zip_int64_t)ctx->start; - need_seek = 0; - } - else { - new_current = (zip_int64_t)ctx->end + args->offset; - } - break; - - case SEEK_CUR: - new_current = (zip_int64_t)ctx->current + args->offset; - break; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end) - || (zip_uint64_t)new_current + ctx->start < ctx->start) { - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; - } - - ctx->current = (zip_uint64_t)new_current; - - if (need_seek) { - if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) { - return -1; - } - } - return 0; - } - - case ZIP_SOURCE_SEEK_WRITE: { - zip_source_args_seek_t *args; - - args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); - if (args == NULL) { - return -1; - } - - if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_STAT: { - if (len < sizeof(ctx->st)) + if ((i = fread(buf, 1, (size_t)n, ctx->f)) == 0) { + if (ferror(ctx->f)) { + zip_error_set(&ctx->error, ZIP_ER_READ, errno); return -1; + } + } + ctx->current += i; + + return (zip_int64_t)i; - if (zip_error_code_zip(&ctx->stat_error) != 0) { - zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error)); + case ZIP_SOURCE_REMOVE: + if (remove(ctx->fname) < 0) { + zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno); + return -1; + } + return 0; + + case ZIP_SOURCE_ROLLBACK_WRITE: + if (ctx->fout) { + fclose(ctx->fout); + ctx->fout = NULL; + } + (void)remove(ctx->tmpname); + free(ctx->tmpname); + ctx->tmpname = NULL; + return 0; + + case ZIP_SOURCE_SEEK: { + zip_int64_t new_current; + int need_seek; + zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + + if (args == NULL) + return -1; + + need_seek = 1; + + switch (args->whence) { + case SEEK_SET: + new_current = args->offset; + break; + + case SEEK_END: + if (ctx->end == 0) { + if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) { + return -1; + } + if ((new_current = ftello(ctx->f)) < 0) { + zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); + return -1; + } + new_current -= (zip_int64_t)ctx->start; + need_seek = 0; + } + else { + new_current = (zip_int64_t)ctx->end + args->offset; + } + break; + + case SEEK_CUR: + new_current = (zip_int64_t)ctx->current + args->offset; + break; + + default: + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end) || (zip_uint64_t)new_current + ctx->start < ctx->start) { + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; + } + + ctx->current = (zip_uint64_t)new_current; + + if (need_seek) { + if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) { return -1; } + } + return 0; + } + + case ZIP_SOURCE_SEEK_WRITE: { + zip_source_args_seek_t *args; - memcpy(data, &ctx->st, sizeof(ctx->st)); - return sizeof(ctx->st); + args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error); + if (args == NULL) { + return -1; } - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; + if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) { + return -1; + } + return 0; + } - case ZIP_SOURCE_TELL: - return (zip_int64_t)ctx->current; + case ZIP_SOURCE_STAT: { + if (len < sizeof(ctx->st)) + return -1; - case ZIP_SOURCE_TELL_WRITE: - { - off_t ret = ftello(ctx->fout); + if (zip_error_code_zip(&ctx->stat_error) != 0) { + zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error)); + return -1; + } - if (ret < 0) { - zip_error_set(&ctx->error, ZIP_ER_TELL, errno); - return -1; - } - return ret; - } + memcpy(data, &ctx->st, sizeof(ctx->st)); + return sizeof(ctx->st); + } - case ZIP_SOURCE_WRITE: - { - size_t ret; + case ZIP_SOURCE_SUPPORTS: + return ctx->supports; - clearerr(ctx->fout); - ret = fwrite(data, 1, len, ctx->fout); - if (ret != len || ferror(ctx->fout)) { - zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); - return -1; - } + case ZIP_SOURCE_TELL: + return (zip_int64_t)ctx->current; - return (zip_int64_t)ret; - } + case ZIP_SOURCE_TELL_WRITE: { + off_t ret = ftello(ctx->fout); - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + if (ret < 0) { + zip_error_set(&ctx->error, ZIP_ER_TELL, errno); + return -1; + } + return ret; + } + + case ZIP_SOURCE_WRITE: { + size_t ret; + + clearerr(ctx->fout); + ret = fwrite(data, 1, len, ctx->fout); + if (ret != len || ferror(ctx->fout)) { + zip_error_set(&ctx->error, ZIP_ER_WRITE, errno); + return -1; + } + + return (zip_int64_t)ret; + } + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } @@ -504,4 +630,3 @@ read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) static int -_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error) -{ +_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error) { if (offset > ZIP_INT64_MAX) { @@ -515,4 +640,3 @@ _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) -{ +_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error) { if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) { diff --git a/src/Common/libzip/zip_source_free.c b/src/Common/libzip/zip_source_free.c index 90704699..7cb35255 100644 --- a/src/Common/libzip/zip_source_free.c +++ b/src/Common/libzip/zip_source_free.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN void -zip_source_free(zip_source_t *src) -{ +zip_source_free(zip_source_t *src) { if (src == NULL) @@ -46,8 +45,8 @@ zip_source_free(zip_source_t *src) if (src->refcount > 0) { - src->refcount--; + src->refcount--; } if (src->refcount > 0) { - return; + return; } - + if (ZIP_SOURCE_IS_OPEN_READING(src)) { @@ -57,13 +56,13 @@ zip_source_free(zip_source_t *src) if (ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_source_rollback_write(src); + zip_source_rollback_write(src); } - + if (src->source_archive && !src->source_closed) { - _zip_deregister_source(src->source_archive, src); + _zip_deregister_source(src->source_archive, src); } - + (void)_zip_source_call(src, NULL, 0, ZIP_SOURCE_FREE); - + if (src->src) { - zip_source_free(src->src); + zip_source_free(src->src); } diff --git a/src/Common/libzip/zip_source_function.c b/src/Common/libzip/zip_source_function.c index 06ce5c97..56eb1c5a 100644 --- a/src/Common/libzip/zip_source_function.c +++ b/src/Common/libzip/zip_source_function.c @@ -2,3 +2,3 @@ zip_source_function.c -- create zip data source from callback function - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,8 +40,7 @@ ZIP_EXTERN zip_source_t * -zip_source_function(zip_t *za, zip_source_callback zcb, void *ud) -{ +zip_source_function(zip_t *za, zip_source_callback zcb, void *ud) { if (za == NULL) { - return NULL; + return NULL; } - + return zip_source_function_create(zcb, ud, &za->error); @@ -51,7 +50,6 @@ zip_source_function(zip_t *za, zip_source_callback zcb, void *ud) ZIP_EXTERN zip_source_t * -zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error) -{ +zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error) { zip_source_t *zs; - if ((zs=_zip_source_new(error)) == NULL) + if ((zs = _zip_source_new(error)) == NULL) return NULL; @@ -60,8 +58,8 @@ zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error zs->ud = ud; - + zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS); if (zs->supports < 0) { - zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; + zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; } - + return zs; @@ -71,4 +69,3 @@ zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error ZIP_EXTERN void -zip_source_keep(zip_source_t *src) -{ +zip_source_keep(zip_source_t *src) { src->refcount++; @@ -78,8 +75,7 @@ zip_source_keep(zip_source_t *src) zip_source_t * -_zip_source_new(zip_error_t *error) -{ +_zip_source_new(zip_error_t *error) { zip_source_t *src; - if ((src=(zip_source_t *)malloc(sizeof(*src))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); + if ((src = (zip_source_t *)malloc(sizeof(*src))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; @@ -97,2 +93,3 @@ _zip_source_new(zip_error_t *error) src->eof = false; + src->had_read_error = false; diff --git a/src/Common/libzip/zip_source_get_compression_flags.c b/src/Common/libzip/zip_source_get_compression_flags.c new file mode 100644 index 00000000..e33e43b1 --- /dev/null +++ b/src/Common/libzip/zip_source_get_compression_flags.c @@ -0,0 +1,57 @@ +/* + zip_source_get_compression_flags.c -- get compression flags for entry + Copyright (C) 2017 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" + +#define ZIP_COMPRESSION_BITFLAG_MAX 3 + +zip_int8_t +zip_source_get_compression_flags(zip_source_t *src) { + while (src) { + if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_COMPRESSION_FLAGS))) { + zip_int64_t ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_GET_COMPRESSION_FLAGS); + if (ret < 0) { + return -1; + } + if (ret > ZIP_COMPRESSION_BITFLAG_MAX) { + zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); + return -1; + } + return (zip_int8_t)ret; + } + src = src->src; + } + + return 0; +} diff --git a/src/Common/libzip/zip_source_is_deleted.c b/src/Common/libzip/zip_source_is_deleted.c index e50cdd9e..1e5d343d 100644 --- a/src/Common/libzip/zip_source_is_deleted.c +++ b/src/Common/libzip/zip_source_is_deleted.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN int -zip_source_is_deleted(zip_source_t *src) -{ +zip_source_is_deleted(zip_source_t *src) { return src->write_state == ZIP_SOURCE_WRITE_REMOVED; diff --git a/src/Common/libzip/zip_source_layered.c b/src/Common/libzip/zip_source_layered.c index 94b33101..5e95bc12 100644 --- a/src/Common/libzip/zip_source_layered.c +++ b/src/Common/libzip/zip_source_layered.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,6 +40,5 @@ zip_source_t * -zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud) -{ +zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud) { if (za == NULL) - return NULL; + return NULL; @@ -50,9 +49,8 @@ zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, zip_source_t * -zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) -{ +zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) { zip_source_t *zs; - - if ((zs=_zip_source_new(error)) == NULL) - return NULL; - + + if ((zs = _zip_source_new(error)) == NULL) + return NULL; + zip_source_keep(src); @@ -64,3 +62,3 @@ zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, voi if (zs->supports < 0) { - zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; + zs->supports = ZIP_SOURCE_SUPPORTS_READABLE; } diff --git a/src/Common/libzip/zip_source_open.c b/src/Common/libzip/zip_source_open.c index a5712b27..187001cd 100644 --- a/src/Common/libzip/zip_source_open.c +++ b/src/Common/libzip/zip_source_open.c @@ -2,3 +2,3 @@ zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,9 +37,8 @@ ZIP_EXTERN int -zip_source_open(zip_source_t *src) -{ +zip_source_open(zip_source_t *src) { if (src->source_closed) { - return -1; + return -1; } if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { - zip_error_set(&src->error, ZIP_ER_DELETED, 0); + zip_error_set(&src->error, ZIP_ER_DELETED, 0); return -1; @@ -60,3 +59,3 @@ zip_source_open(zip_source_t *src) } - + if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) { @@ -70,5 +69,6 @@ zip_source_open(zip_source_t *src) src->eof = false; + src->had_read_error = false; _zip_error_clear(&src->error); src->open_count++; - + return 0; diff --git a/src/Common/libzip/zip_source_pkware.c b/src/Common/libzip/zip_source_pkware.c index 3957d993..b466da47 100644 --- a/src/Common/libzip/zip_source_pkware.c +++ b/src/Common/libzip/zip_source_pkware.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -44,13 +44,11 @@ struct trad_pkware { -#define HEADERLEN 12 -#define KEY0 305419896 -#define KEY1 591751049 -#define KEY2 878082192 +#define HEADERLEN 12 +#define KEY0 305419896 +#define KEY1 591751049 +#define KEY2 878082192 -static void decrypt(struct trad_pkware *, zip_uint8_t *, - const zip_uint8_t *, zip_uint64_t, int); +static void decrypt(struct trad_pkware *, zip_uint8_t *, const zip_uint8_t *, zip_uint64_t, int); static int decrypt_header(zip_source_t *, struct trad_pkware *); -static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, - zip_uint64_t, zip_source_cmd_t); +static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t); static void pkware_free(struct trad_pkware *); @@ -59,5 +57,3 @@ static void pkware_free(struct trad_pkware *); zip_source_t * -zip_source_pkware(zip_t *za, zip_source_t *src, - zip_uint16_t em, int flags, const char *password) -{ +zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { struct trad_pkware *ctx; @@ -74,3 +70,3 @@ zip_source_pkware(zip_t *za, zip_source_t *src, - if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { + if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(&za->error, ZIP_ER_MEMORY, 0); @@ -86,3 +82,3 @@ zip_source_pkware(zip_t *za, zip_source_t *src, - if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) { + if ((s2 = zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) { pkware_free(ctx); @@ -96,5 +92,3 @@ zip_source_pkware(zip_t *za, zip_source_t *src, static void -decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, - zip_uint64_t len, int update_only) -{ +decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len, int update_only) { zip_uint16_t tmp; @@ -103,3 +97,3 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, - for (i=0; i<len; i++) { + for (i = 0; i < len; i++) { b = in[i]; @@ -127,4 +121,3 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, static int -decrypt_header(zip_source_t *src, struct trad_pkware *ctx) -{ +decrypt_header(zip_source_t *src, struct trad_pkware *ctx) { zip_uint8_t header[HEADERLEN]; @@ -134,9 +127,9 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) - if ((n=zip_source_read(src, header, HEADERLEN)) < 0) { - _zip_error_set_from_source(&ctx->error, src); + if ((n = zip_source_read(src, header, HEADERLEN)) < 0) { + _zip_error_set_from_source(&ctx->error, src); return -1; } - + if (n != HEADERLEN) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); + zip_error_set(&ctx->error, ZIP_ER_EOF, 0); return -1; @@ -153,4 +146,4 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) - if (header[HEADERLEN-1] != st.crc>>24 && header[HEADERLEN-1] != dostime>>8) { - zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0); + if (header[HEADERLEN - 1] != st.crc >> 24 && header[HEADERLEN - 1] != dostime >> 8) { + zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0); return -1; @@ -163,5 +156,3 @@ decrypt_header(zip_source_t *src, struct trad_pkware *ctx) static zip_int64_t -pkware_decrypt(zip_source_t *src, void *ud, void *data, - zip_uint64_t len, zip_source_cmd_t cmd) -{ +pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct trad_pkware *ctx; @@ -172,47 +163,46 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, switch (cmd) { - case ZIP_SOURCE_OPEN: - if (decrypt_header(src, ctx) < 0) - return -1; - return 0; - - case ZIP_SOURCE_READ: - if ((n=zip_source_read(src, data, len)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - - decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0); - return n; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: - { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - st->encryption_method = ZIP_EM_NONE; - st->valid |= ZIP_STAT_ENCRYPTION_METHOD; - /* TODO: deduce HEADERLEN from size for uncompressed */ - if (st->valid & ZIP_STAT_COMP_SIZE) - st->comp_size -= HEADERLEN; - - return 0; - } - - case ZIP_SOURCE_SUPPORTS: - return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1); - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - pkware_free(ctx); - return 0; - - default: - zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); - return -1; + case ZIP_SOURCE_OPEN: + if (decrypt_header(src, ctx) < 0) + return -1; + return 0; + + case ZIP_SOURCE_READ: + if ((n = zip_source_read(src, data, len)) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + + decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0); + return n; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + st = (zip_stat_t *)data; + + st->encryption_method = ZIP_EM_NONE; + st->valid |= ZIP_STAT_ENCRYPTION_METHOD; + /* TODO: deduce HEADERLEN from size for uncompressed */ + if (st->valid & ZIP_STAT_COMP_SIZE) + st->comp_size -= HEADERLEN; + + return 0; + } + + case ZIP_SOURCE_SUPPORTS: + return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1); + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + pkware_free(ctx); + return 0; + + default: + zip_error_set(&ctx->error, ZIP_ER_INVAL, 0); + return -1; } @@ -222,4 +212,3 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, static void -pkware_free(struct trad_pkware *ctx) -{ +pkware_free(struct trad_pkware *ctx) { free(ctx); diff --git a/src/Common/libzip/zip_source_read.c b/src/Common/libzip/zip_source_read.c index 267128ba..83514c6e 100644 --- a/src/Common/libzip/zip_source_read.c +++ b/src/Common/libzip/zip_source_read.c @@ -2,3 +2,3 @@ zip_source_read.c -- read data from zip_source - Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ zip_int64_t -zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) -{ +zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) { zip_uint64_t bytes_read; @@ -44,6 +43,6 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) if (src->source_closed) { - return -1; + return -1; } if (!ZIP_SOURCE_IS_OPEN_READING(src) || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); + zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; @@ -51,3 +50,3 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) - if (_zip_source_had_error(src)) { + if (src->had_read_error) { return -1; @@ -59,2 +58,6 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) + if (len == 0) { + return 0; + } + bytes_read = 0; @@ -62,2 +65,3 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) if ((n = _zip_source_call(src, (zip_uint8_t *)data + bytes_read, len - bytes_read, ZIP_SOURCE_READ)) < 0) { + src->had_read_error = true; if (bytes_read == 0) { @@ -83,4 +87,3 @@ zip_source_read(zip_source_t *src, void *data, zip_uint64_t len) bool -_zip_source_eof(zip_source_t *src) -{ +_zip_source_eof(zip_source_t *src) { return src->eof; diff --git a/src/Common/libzip/zip_source_remove.c b/src/Common/libzip/zip_source_remove.c index 470a5eda..8e01e24d 100644 --- a/src/Common/libzip/zip_source_remove.c +++ b/src/Common/libzip/zip_source_remove.c @@ -3,6 +3,6 @@ Copyright (C) 2014 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 @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,8 +38,7 @@ int -zip_source_remove(zip_source_t *src) -{ +zip_source_remove(zip_source_t *src) { if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { - return 0; + return 0; } - + if (ZIP_SOURCE_IS_OPEN_READING(src)) { @@ -50,11 +49,11 @@ zip_source_remove(zip_source_t *src) if (src->write_state != ZIP_SOURCE_WRITE_CLOSED) { - zip_source_rollback_write(src); + zip_source_rollback_write(src); } - + if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_REMOVE) < 0) { - return -1; + return -1; } - + src->write_state = ZIP_SOURCE_WRITE_REMOVED; - + return 0; diff --git a/src/Common/libzip/zip_source_rollback_write.c b/src/Common/libzip/zip_source_rollback_write.c index c35f30f9..bbccaf82 100644 --- a/src/Common/libzip/zip_source_rollback_write.c +++ b/src/Common/libzip/zip_source_rollback_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN void -zip_source_rollback_write(zip_source_t *src) -{ +zip_source_rollback_write(zip_source_t *src) { if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) { @@ -43,3 +42,3 @@ zip_source_rollback_write(zip_source_t *src) } - + _zip_source_call(src, NULL, 0, ZIP_SOURCE_ROLLBACK_WRITE); diff --git a/src/Common/libzip/zip_source_seek.c b/src/Common/libzip/zip_source_seek.c index c3f47036..aed53b87 100644 --- a/src/Common/libzip/zip_source_seek.c +++ b/src/Common/libzip/zip_source_seek.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,12 +38,11 @@ ZIP_EXTERN int -zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence) -{ +zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence) { zip_source_args_seek_t args; - + if (src->source_closed) { - return -1; + return -1; } if (!ZIP_SOURCE_IS_OPEN_READING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } @@ -52,3 +51,3 @@ zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence) args.whence = whence; - + return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0); @@ -58,34 +57,33 @@ zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence) 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_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; + 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; + 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; + zip_error_set(error, ZIP_ER_INVAL, 0); + return -1; } - + return new_offset; diff --git a/src/Common/libzip/zip_source_seek_write.c b/src/Common/libzip/zip_source_seek_write.c index 66607664..4ecbee18 100644 --- a/src/Common/libzip/zip_source_seek_write.c +++ b/src/Common/libzip/zip_source_seek_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,14 +38,13 @@ ZIP_EXTERN int -zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) -{ +zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence) { zip_source_args_seek_t args; - + if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + args.offset = offset; args.whence = whence; - + return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK_WRITE) < 0 ? -1 : 0); diff --git a/src/Common/libzip/zip_source_stat.c b/src/Common/libzip/zip_source_stat.c index 864507e1..987c8620 100644 --- a/src/Common/libzip/zip_source_stat.c +++ b/src/Common/libzip/zip_source_stat.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ ZIP_EXTERN int -zip_source_stat(zip_source_t *src, zip_stat_t *st) -{ +zip_source_stat(zip_source_t *src, zip_stat_t *st) { if (src->source_closed) { - return -1; + return -1; } if (st == NULL) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); + zip_error_set(&src->error, ZIP_ER_INVAL, 0); return -1; @@ -49,8 +48,8 @@ zip_source_stat(zip_source_t *src, zip_stat_t *st) zip_stat_init(st); - + if (ZIP_SOURCE_IS_LAYERED(src)) { - if (zip_source_stat(src->src, st) < 0) { - _zip_error_set_from_source(&src->error, src->src); - return -1; - } + if (zip_source_stat(src->src, st) < 0) { + _zip_error_set_from_source(&src->error, src->src); + return -1; + } } diff --git a/src/Common/libzip/zip_source_supports.c b/src/Common/libzip/zip_source_supports.c index c59aa1f8..a47f293e 100644 --- a/src/Common/libzip/zip_source_supports.c +++ b/src/Common/libzip/zip_source_supports.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ zip_int64_t -zip_source_supports(zip_source_t *src) -{ +zip_source_supports(zip_source_t *src) { return src->supports; @@ -47,21 +46,19 @@ zip_source_supports(zip_source_t *src) ZIP_EXTERN zip_int64_t -zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) -{ +zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) { zip_int64_t bitmap; va_list ap; - + bitmap = ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd0); - - - + + va_start(ap, cmd0); for (;;) { - int cmd = va_arg(ap, int); - if (cmd < 0) { - break; - } - bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd); + int cmd = va_arg(ap, int); + if (cmd < 0) { + break; + } + bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd); } va_end(ap); - + return bitmap; diff --git a/src/Common/libzip/zip_source_tell.c b/src/Common/libzip/zip_source_tell.c index f1c10b5b..ab418fa0 100644 --- a/src/Common/libzip/zip_source_tell.c +++ b/src/Common/libzip/zip_source_tell.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,12 +38,11 @@ ZIP_EXTERN zip_int64_t -zip_source_tell(zip_source_t *src) -{ +zip_source_tell(zip_source_t *src) { if (src->source_closed) { - return -1; + return -1; } if (!ZIP_SOURCE_IS_OPEN_READING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL); diff --git a/src/Common/libzip/zip_source_tell_write.c b/src/Common/libzip/zip_source_tell_write.c index 2fa15072..f7a8a3f6 100644 --- a/src/Common/libzip/zip_source_tell_write.c +++ b/src/Common/libzip/zip_source_tell_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ ZIP_EXTERN zip_int64_t -zip_source_tell_write(zip_source_t *src) -{ +zip_source_tell_write(zip_source_t *src) { if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL_WRITE); diff --git a/src/Common/libzip/zip_source_win32a.c b/src/Common/libzip/zip_source_win32a.c index 85493b66..0780fa50 100644 --- a/src/Common/libzip/zip_source_win32a.c +++ b/src/Common/libzip/zip_source_win32a.c @@ -1,36 +1,42 @@ /* -zip_source_win32a.c -- create data source from Windows file (ANSI) -Copyright (C) 1999-2016 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. + zip_source_win32a.c -- create data source from Windows file (ANSI) + Copyright (C) 1999-2017 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. */ +/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ +#if !defined(MS_UWP) && !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> #include <stdio.h> +#include <stdlib.h> @@ -39,3 +45,3 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -static void * _win32_strdup_a(const void *str); +static void *_win32_strdup_a(const void *str); static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx); @@ -45,2 +51,3 @@ static int _win32_remove_a(const void *fname); +// clang-format off static _zip_source_win32_file_ops_t win32_ops_a = { @@ -52,6 +59,6 @@ static _zip_source_win32_file_ops_t win32_ops_a = { }; +// clang-format on ZIP_EXTERN zip_source_t * -zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) -{ +zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -64,4 +71,3 @@ zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t ZIP_EXTERN zip_source_t * -zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { if (fname == NULL || length < -1) { @@ -76,4 +82,3 @@ zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t leng static void * -_win32_strdup_a(const void *str) -{ +_win32_strdup_a(const void *str) { return strdup((const char *)str); @@ -83,4 +88,3 @@ _win32_strdup_a(const void *str) static HANDLE -_win32_open_a(_zip_source_win32_read_file_t *ctx) -{ +_win32_open_a(_zip_source_win32_read_file_t *ctx) { return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -90,5 +94,4 @@ _win32_open_a(_zip_source_win32_read_file_t *ctx) static HANDLE -_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) -{ - int len; +_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) { + size_t len; @@ -110,4 +113,3 @@ _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) -{ +_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx) { if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) @@ -119,4 +121,3 @@ _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx) static int -_win32_remove_a(const void *fname) -{ +_win32_remove_a(const void *fname) { DeleteFileA((const char *)fname); diff --git a/src/Common/libzip/zip_source_win32handle.c b/src/Common/libzip/zip_source_win32handle.c index 7fe003dc..8cef9198 100644 --- a/src/Common/libzip/zip_source_win32handle.c +++ b/src/Common/libzip/zip_source_win32handle.c @@ -1,32 +1,32 @@ /* -zip_source_win32file.c -- create data source from HANDLE (Win32) -Copyright (C) 1999-2016 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. + zip_source_win32file.c -- create data source from HANDLE (Win32) + Copyright (C) 1999-2016 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. */ @@ -34,5 +34,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include <wchar.h> +#include <aclapi.h> #include <stdlib.h> #include <string.h> +#include <wchar.h> @@ -50,4 +51,3 @@ static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_ ZIP_EXTERN zip_source_t * -zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) -{ +zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -60,4 +60,3 @@ zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len) ZIP_EXTERN zip_source_t * -zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { if (h == INVALID_HANDLE_VALUE || length < -1) { @@ -72,4 +71,3 @@ zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_source_t * -_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error) -{ +_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error) { _zip_source_win32_read_file_t *ctx; @@ -142,4 +140,3 @@ _zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start static zip_int64_t -_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) -{ +_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { _zip_source_win32_read_file_t *ctx; @@ -349,4 +346,4 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd if (win32err == ERROR_FILE_NOT_FOUND || win32err == ERROR_PATH_NOT_FOUND) { - zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT); - return -1; + zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT); + return -1; } @@ -378,4 +375,3 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd - case ZIP_SOURCE_TELL_WRITE: - { + case ZIP_SOURCE_TELL_WRITE: { LARGE_INTEGER zero; @@ -392,4 +388,3 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd - case ZIP_SOURCE_WRITE: - { + case ZIP_SOURCE_WRITE: { DWORD ret; @@ -411,4 +406,3 @@ _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd static int -_win32_create_temp_file(_zip_source_win32_read_file_t *ctx) -{ +_win32_create_temp_file(_zip_source_win32_read_file_t *ctx) { zip_uint32_t value; @@ -422,8 +416,8 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) void *temp = NULL; - SECURITY_INFORMATION si; - SECURITY_ATTRIBUTES sa; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_ATTRIBUTES psa = NULL; - DWORD len; - BOOL success; + SECURITY_ATTRIBUTES sa; + SECURITY_INFORMATION si; + DWORD success; + PACL dacl = NULL; @@ -436,12 +430,4 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; - len = 0; - success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len); - if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) { - zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0); - return -1; - } - success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len); - } - if (success) { + success = GetSecurityInfo(ctx->h, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd); + if (success == ERROR_SUCCESS) { sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -453,3 +439,9 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) + +#ifndef MS_UWP value = GetTickCount(); +#else + value = (zip_uint32_t)GetTickCount64(); +#endif + for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) { @@ -462,3 +454,3 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) free(temp); - free(psd); + LocalFree(psd); zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError())); @@ -467,3 +459,3 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) - free(psd); + LocalFree(psd); ctx->hout = th; @@ -476,4 +468,3 @@ _win32_create_temp_file(_zip_source_win32_read_file_t *ctx) static int -_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error) -{ +_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error) { if (offset > ZIP_INT64_MAX) { @@ -487,4 +478,3 @@ _zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error) static int -_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error) -{ +_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error) { LARGE_INTEGER li; @@ -518,4 +508,3 @@ _zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error) static int -_zip_win32_error_to_errno(DWORD win32err) -{ +_zip_win32_error_to_errno(DWORD win32err) { /* @@ -545,4 +534,3 @@ _zip_win32_error_to_errno(DWORD win32err) static int -_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx) -{ +_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx) { FILETIME mtimeft; @@ -588,4 +576,3 @@ _zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx) static int -_zip_filetime_to_time_t(FILETIME ft, time_t *t) -{ +_zip_filetime_to_time_t(FILETIME ft, time_t *t) { /* diff --git a/src/Common/libzip/zip_source_win32utf8.c b/src/Common/libzip/zip_source_win32utf8.c index 004c66ac..1e279b02 100644 --- a/src/Common/libzip/zip_source_win32utf8.c +++ b/src/Common/libzip/zip_source_win32utf8.c @@ -1,36 +1,41 @@ /* -zip_source_win32utf8.c -- create data source from Windows file (UTF-8) -Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner + zip_source_win32utf8.c -- create data source from Windows file (UTF-8) + Copyright (C) 1999-2015 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> + 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. + 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. + 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. */ +/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ +#if !defined(MS_UWP) && !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> -#include <stdio.h> +#include <stdlib.h> @@ -41,4 +46,3 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ZIP_EXTERN zip_source_t * -zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) -{ +zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -51,4 +55,3 @@ zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t le ZIP_EXTERN zip_source_t * -zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { int size; diff --git a/src/Common/libzip/zip_source_win32w.c b/src/Common/libzip/zip_source_win32w.c index 551aba5f..5583bdff 100644 --- a/src/Common/libzip/zip_source_win32w.c +++ b/src/Common/libzip/zip_source_win32w.c @@ -1,36 +1,42 @@ /* -zip_source_win32w.c -- create data source from Windows file (UTF-16) -Copyright (C) 1999-2016 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. + zip_source_win32w.c -- create data source from Windows file (UTF-16) + Copyright (C) 1999-2017 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. */ +/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ +#if !defined(MS_UWP) && !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0501 +#endif +#include <windows.h> #include <stdio.h> +#include <stdlib.h> @@ -39,3 +45,3 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -static void * _win32_strdup_w(const void *str); +static void *_win32_strdup_w(const void *str); static HANDLE _win32_open_w(_zip_source_win32_read_file_t *ctx); @@ -45,2 +51,3 @@ static int _win32_remove_w(const void *fname); +// clang-format off static _zip_source_win32_file_ops_t win32_ops_w = { @@ -52,6 +59,6 @@ static _zip_source_win32_file_ops_t win32_ops_w = { }; +// clang-format on ZIP_EXTERN zip_source_t * -zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) -{ +zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) { if (za == NULL) @@ -64,4 +71,3 @@ zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64 ZIP_EXTERN zip_source_t * -zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) -{ +zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error) { if (fname == NULL || length < -1) { @@ -76,4 +82,3 @@ zip_source_win32w_create(const wchar_t *fname, zip_uint64_t start, zip_int64_t l static void * -_win32_strdup_w(const void *str) -{ +_win32_strdup_w(const void *str) { return _wcsdup((const wchar_t *)str); @@ -83,5 +88,16 @@ _win32_strdup_w(const void *str) static HANDLE -_win32_open_w(_zip_source_win32_read_file_t *ctx) -{ +_win32_open_w(_zip_source_win32_read_file_t *ctx) { +#ifdef MS_UWP + CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; + extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; + extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extParams.dwSize = sizeof(extParams); + extParams.hTemplateFile = NULL; + extParams.lpSecurityAttributes = NULL; + + return CreateFile2(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &extParams); +#else return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +#endif } @@ -90,5 +106,4 @@ _win32_open_w(_zip_source_win32_read_file_t *ctx) static HANDLE -_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) -{ - int len; +_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) { + size_t len; @@ -105,3 +120,15 @@ _win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32 +#ifdef MS_UWP + CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; + extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY; + extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS; + extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extParams.dwSize = sizeof(extParams); + extParams.hTemplateFile = NULL; + extParams.lpSecurityAttributes = NULL; + + return CreateFile2((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, CREATE_NEW, &extParams); +#else return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL); +#endif } @@ -110,4 +137,3 @@ _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) -{ +_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) { if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) @@ -119,4 +145,3 @@ _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) static int -_win32_remove_w(const void *fname) -{ +_win32_remove_w(const void *fname) { DeleteFileW((const wchar_t *)fname); diff --git a/src/Common/libzip/zip_source_window.c b/src/Common/libzip/zip_source_window.c index f02d048c..f4701a04 100644 --- a/src/Common/libzip/zip_source_window.c +++ b/src/Common/libzip/zip_source_window.c @@ -2,3 +2,3 @@ zip_source_window.c -- return part of lower source - Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,6 +40,13 @@ struct window { - zip_uint64_t start; - zip_uint64_t end; - zip_uint64_t offset; + zip_uint64_t start; /* where in file we start reading */ + zip_uint64_t end; /* where in file we stop reading */ + + /* if not NULL, read file data for this file */ + zip_t *source_archive; + zip_uint64_t source_index; + + zip_uint64_t offset; /* offset in src for next read */ + zip_stat_t stat; + zip_int8_t compression_flags; zip_error_t error; @@ -53,5 +60,4 @@ static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip zip_source_t * -zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t len) -{ - return _zip_source_window_new(src, start, len, NULL, &za->error); +zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t len) { + return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, &za->error); } @@ -60,16 +66,15 @@ zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t zip_source_t * -_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_error_t *error) -{ +_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) { struct window *ctx; - - if (src == NULL || start + length < start) { - zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; + + if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) { + zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; } - - if ((ctx=(struct window *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ER_MEMORY, 0); - return NULL; + + if ((ctx = (struct window *)malloc(sizeof(*ctx))) == NULL) { + zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; } - + ctx->start = start; @@ -77,13 +82,16 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt zip_stat_init(&ctx->stat); + ctx->compression_flags = compression_flags; + ctx->source_archive = source_archive; + ctx->source_index = source_index; zip_error_init(&ctx->error); - ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1)); + ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1)); ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false; - + if (st) { - if (_zip_stat_merge(&ctx->stat, st, error) < 0) { - free(ctx); - return NULL; - } + if (_zip_stat_merge(&ctx->stat, st, error) < 0) { + free(ctx); + return NULL; + } } - + return zip_source_layered_create(src, window_read, ctx, error); @@ -93,4 +101,3 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt int -_zip_source_set_source_archive(zip_source_t *src, zip_t *za) -{ +_zip_source_set_source_archive(zip_source_t *src, zip_t *za) { src->source_archive = za; @@ -102,4 +109,3 @@ _zip_source_set_source_archive(zip_source_t *src, zip_t *za) void -_zip_source_invalidate(zip_source_t *src) -{ +_zip_source_invalidate(zip_source_t *src) { src->source_closed = 1; @@ -107,3 +113,3 @@ _zip_source_invalidate(zip_source_t *src) if (zip_error_code_zip(&src->error) == ZIP_ER_OK) { - zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0); + zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0); } @@ -113,4 +119,3 @@ _zip_source_invalidate(zip_source_t *src) static zip_int64_t -window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) -{ +window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) { struct window *ctx; @@ -123,92 +128,108 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou switch (cmd) { - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_ERROR: - return zip_error_to_data(&ctx->error, data, len); - - case ZIP_SOURCE_FREE: - free(ctx); - return 0; - - case ZIP_SOURCE_OPEN: - if (!ctx->needs_seek) { - for (n=0; n<ctx->start; n+=(zip_uint64_t)ret) { - i = (ctx->start-n > sizeof(b) ? sizeof(b) : ctx->start-n); - if ((ret=zip_source_read(src, b, i)) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - if (ret==0) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - } - - } - ctx->offset = ctx->start; - return 0; - - case ZIP_SOURCE_READ: - if (len > ctx->end - ctx->offset) - len = ctx->end - ctx->offset; - - if (len == 0) - return 0; - - if (ctx->needs_seek) { - if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&ctx->error, src); - return -1; - } - } - - if ((ret=zip_source_read(src, data, len)) < 0) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - - ctx->offset += (zip_uint64_t)ret; - - if (ret == 0) { - if (ctx->offset < ctx->end) { - zip_error_set(&ctx->error, ZIP_ER_EOF, 0); - return -1; - } - } - return ret; - - case ZIP_SOURCE_SEEK: - { - zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); - - if (new_offset < 0) { - return -1; - } - - ctx->offset = (zip_uint64_t)new_offset + ctx->start; - return 0; - } - - case ZIP_SOURCE_STAT: - { - zip_stat_t *st; - - st = (zip_stat_t *)data; - - if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) { - return -1; - } - return 0; - } - - case ZIP_SOURCE_SUPPORTS: - return ctx->supports; - - case ZIP_SOURCE_TELL: - return (zip_int64_t)(ctx->offset - ctx->start); - - default: - zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); - return -1; + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_ERROR: + return zip_error_to_data(&ctx->error, data, len); + + case ZIP_SOURCE_FREE: + free(ctx); + return 0; + + case ZIP_SOURCE_OPEN: + if (ctx->source_archive) { + zip_uint64_t offset; + + if ((offset = _zip_file_get_offset(ctx->source_archive, ctx->source_index, &ctx->error)) == 0) { + return -1; + } + if (ctx->end + offset < ctx->end) { + /* zip archive data claims end of data past zip64 limits */ + zip_error_set(&ctx->error, ZIP_ER_INCONS, 0); + return -1; + } + ctx->start += offset; + ctx->end += offset; + ctx->source_archive = NULL; + } + + if (!ctx->needs_seek) { + for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) { + i = (ctx->start - n > sizeof(b) ? sizeof(b) : ctx->start - n); + if ((ret = zip_source_read(src, b, i)) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + if (ret == 0) { + zip_error_set(&ctx->error, ZIP_ER_EOF, 0); + return -1; + } + } + } + ctx->offset = ctx->start; + return 0; + + case ZIP_SOURCE_READ: + if (len > ctx->end - ctx->offset) + len = ctx->end - ctx->offset; + + if (len == 0) + return 0; + + if (ctx->needs_seek) { + if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) { + _zip_error_set_from_source(&ctx->error, src); + return -1; + } + } + + if ((ret = zip_source_read(src, data, len)) < 0) { + zip_error_set(&ctx->error, ZIP_ER_EOF, 0); + return -1; + } + + ctx->offset += (zip_uint64_t)ret; + + if (ret == 0) { + if (ctx->offset < ctx->end) { + zip_error_set(&ctx->error, ZIP_ER_EOF, 0); + return -1; + } + } + return ret; + + case ZIP_SOURCE_SEEK: { + zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error); + + if (new_offset < 0) { + return -1; + } + + ctx->offset = (zip_uint64_t)new_offset + ctx->start; + return 0; + } + + case ZIP_SOURCE_STAT: { + zip_stat_t *st; + + st = (zip_stat_t *)data; + + if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) { + return -1; + } + return 0; + } + + case ZIP_SOURCE_GET_COMPRESSION_FLAGS: + return ctx->compression_flags; + + case ZIP_SOURCE_SUPPORTS: + return ctx->supports; + + case ZIP_SOURCE_TELL: + return (zip_int64_t)(ctx->offset - ctx->start); + + default: + zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0); + return -1; } @@ -218,12 +239,11 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou void -_zip_deregister_source(zip_t *za, zip_source_t *src) -{ +_zip_deregister_source(zip_t *za, zip_source_t *src) { unsigned int i; - - for (i=0; i<za->nopen_source; i++) { - if (za->open_source[i] == src) { - za->open_source[i] = za->open_source[za->nopen_source-1]; - za->nopen_source--; - break; - } + + for (i = 0; i < za->nopen_source; i++) { + if (za->open_source[i] == src) { + za->open_source[i] = za->open_source[za->nopen_source - 1]; + za->nopen_source--; + break; + } } @@ -233,20 +253,19 @@ _zip_deregister_source(zip_t *za, zip_source_t *src) int -_zip_register_source(zip_t *za, zip_source_t *src) -{ +_zip_register_source(zip_t *za, zip_source_t *src) { zip_source_t **open_source; - - if (za->nopen_source+1 >= za->nopen_source_alloc) { - unsigned int n; - n = za->nopen_source_alloc + 10; - open_source = (zip_source_t **)realloc(za->open_source, n*sizeof(zip_source_t *)); - if (open_source == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - za->nopen_source_alloc = n; - za->open_source = open_source; + + if (za->nopen_source + 1 >= za->nopen_source_alloc) { + unsigned int n; + n = za->nopen_source_alloc + 10; + open_source = (zip_source_t **)realloc(za->open_source, n * sizeof(zip_source_t *)); + if (open_source == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + za->nopen_source_alloc = n; + za->open_source = open_source; } - + za->open_source[za->nopen_source++] = src; - + return 0; diff --git a/src/Common/libzip/zip_source_write.c b/src/Common/libzip/zip_source_write.c index c98f5679..1646e339 100644 --- a/src/Common/libzip/zip_source_write.c +++ b/src/Common/libzip/zip_source_write.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,9 +38,8 @@ ZIP_EXTERN zip_int64_t -zip_source_write(zip_source_t *src, const void *data, zip_uint64_t length) -{ +zip_source_write(zip_source_t *src, const void *data, zip_uint64_t length) { if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || length > ZIP_INT64_MAX) { - zip_error_set(&src->error, ZIP_ER_INVAL, 0); - return -1; + zip_error_set(&src->error, ZIP_ER_INVAL, 0); + return -1; } - + return _zip_source_call(src, (void *)data, length, ZIP_SOURCE_WRITE); diff --git a/src/Common/libzip/zip_source_zip.c b/src/Common/libzip/zip_source_zip.c index e172ca20..b3f1805c 100644 --- a/src/Common/libzip/zip_source_zip.c +++ b/src/Common/libzip/zip_source_zip.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,13 +41,11 @@ ZIP_EXTERN zip_source_t * -zip_source_zip(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, - zip_flags_t flags, zip_uint64_t start, zip_int64_t len) -{ +zip_source_zip(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { if (len < -1) { - zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; + zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; } - + if (len == -1) len = 0; - + if (start == 0 && len == 0) diff --git a/src/Common/libzip/zip_source_zip_new.c b/src/Common/libzip/zip_source_zip_new.c index 92562558..a5cfee3a 100644 --- a/src/Common/libzip/zip_source_zip_new.c +++ b/src/Common/libzip/zip_source_zip_new.c @@ -2,3 +2,3 @@ zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip - Copyright (C) 2012-2016 Dieter Baron and Thomas Klausner + Copyright (C) 2012-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,9 +40,6 @@ zip_source_t * -_zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password) -{ - zip_compression_implementation comp_impl; - zip_encryption_implementation enc_impl; +_zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t flags, zip_uint64_t start, zip_uint64_t len, const char *password) { zip_source_t *src, *s2; - zip_uint64_t offset; struct zip_stat st; + bool partial_data, needs_crc, needs_decrypt, needs_decompress; @@ -56,4 +53,3 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - if ((flags & ZIP_FL_UNCHANGED) == 0 - && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].deleted)) { + if ((flags & ZIP_FL_UNCHANGED) == 0 && (ZIP_ENTRY_DATA_CHANGED(srcza->entry + srcidx) || srcza->entry[srcidx].deleted)) { zip_error_set(&za->error, ZIP_ER_CHANGED, 0); @@ -62,3 +58,3 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) { + if (zip_stat_index(srcza, srcidx, flags | ZIP_FL_UNCHANGED, &st) < 0) { zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); @@ -76,3 +72,3 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl /* overflow or past end of file */ - if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) { + if ((start > 0 || len > 0) && (start + len < start || start + len > st.size)) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -81,13 +77,18 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - enc_impl = NULL; - if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) { - if (password == NULL) { - password = za->default_password; - } + if (len == 0) { + len = st.size - start; + } + + partial_data = len < st.size; + needs_decrypt = ((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE); + needs_decompress = ((flags & ZIP_FL_COMPRESSED) == 0) && (st.comp_method != ZIP_CM_STORE); + /* when reading the whole file, check for CRC errors */ + needs_crc = ((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && !partial_data; + + if (needs_decrypt) { if (password == NULL) { - zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); - return NULL; + password = za->default_password; } - if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + if (password == NULL) { + zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); return NULL; @@ -96,15 +97,2 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - comp_impl = NULL; - if ((flags & ZIP_FL_COMPRESSED) == 0) { - if (st.comp_method != ZIP_CM_STORE) { - if ((comp_impl=_zip_get_compression_implementation(st.comp_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - return NULL; - } - } - } - - if ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0) - return NULL; - if (st.comp_size == 0) { @@ -113,12 +101,12 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) { + if (partial_data && !needs_decrypt && !needs_decompress) { struct zip_stat st2; - - st2.size = len ? len : st.size-start; - st2.comp_size = st2.size; + + st2.size = len; + st2.comp_size = len; st2.comp_method = ZIP_CM_STORE; st2.mtime = st.mtime; - st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME; - - if ((src = _zip_source_window_new(srcza->src, offset+start, st2.size, &st2, &za->error)) == NULL) { + st2.valid = ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_MTIME; + + if ((src = _zip_source_window_new(srcza->src, start, len, &st2, 0, srcza, srcidx, &za->error)) == NULL) { return NULL; @@ -127,3 +115,8 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl else { - if ((src = _zip_source_window_new(srcza->src, offset, st.comp_size, &st, &za->error)) == NULL) { + zip_dirent_t *de; + + if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) { + return NULL; + } + if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, (de->bitflags >> 1) & 3, srcza, srcidx, &za->error)) == NULL) { return NULL; @@ -131,3 +124,3 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl } - + if (_zip_source_set_source_archive(src, srcza) < 0) { @@ -138,4 +131,11 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl /* creating a layered source calls zip_keep() on the lower layer, so we free it */ - - if (enc_impl) { + + if (needs_decrypt) { + zip_encryption_implementation enc_impl; + + if ((enc_impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { + zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + return NULL; + } + s2 = enc_impl(za, src, st.encryption_method, 0, password); @@ -147,4 +147,4 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl } - if (comp_impl) { - s2 = comp_impl(za, src, st.comp_method, 0); + if (needs_decompress) { + s2 = zip_source_decompress(za, src, st.comp_method); zip_source_free(src); @@ -155,4 +155,3 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl } - if (((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) && (len == 0 || len == st.comp_size)) { - /* when reading the whole file, check for CRC errors */ + if (needs_crc) { s2 = zip_source_crc(za, src, 1); @@ -165,4 +164,4 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl - if (start+len > 0 && (comp_impl || enc_impl)) { - s2 = zip_source_window(za, src, start, len ? len : st.size-start); + if (partial_data && (needs_decrypt || needs_decompress)) { + s2 = zip_source_window(za, src, start, len); zip_source_free(src); diff --git a/src/Common/libzip/zip_stat.c b/src/Common/libzip/zip_stat.c index cf8e5661..02cca373 100644 --- a/src/Common/libzip/zip_stat.c +++ b/src/Common/libzip/zip_stat.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,7 +38,6 @@ ZIP_EXTERN int -zip_stat(zip_t *za, const char *fname, zip_flags_t flags, zip_stat_t *st) -{ +zip_stat(zip_t *za, const char *fname, zip_flags_t flags, zip_stat_t *st) { zip_int64_t idx; - if ((idx=zip_name_locate(za, fname, flags)) < 0) + if ((idx = zip_name_locate(za, fname, flags)) < 0) return -1; diff --git a/src/Common/libzip/zip_stat_index.c b/src/Common/libzip/zip_stat_index.c index a2ef59bb..109c1188 100644 --- a/src/Common/libzip/zip_stat_index.c +++ b/src/Common/libzip/zip_stat_index.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,5 +38,3 @@ ZIP_EXTERN int -zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, - zip_stat_t *st) -{ +zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) { const char *name; @@ -44,11 +42,10 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, - if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL) + if ((de = _zip_get_dirent(za, index, flags, NULL)) == NULL) return -1; - if ((name=zip_get_name(za, index, flags)) == NULL) + if ((name = zip_get_name(za, index, flags)) == NULL) return -1; - - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(za->entry+index)) { + + if ((flags & ZIP_FL_UNCHANGED) == 0 && ZIP_ENTRY_DATA_CHANGED(za->entry + index)) { if (zip_source_stat(za->entry[index].source, st) < 0) { @@ -67,4 +64,3 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, st->encryption_method = de->encryption_method; - st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE|ZIP_STAT_MTIME - |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD; + st->valid = (de->crc_valid ? ZIP_STAT_CRC : 0) | ZIP_STAT_SIZE | ZIP_STAT_MTIME | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD; } @@ -73,4 +69,4 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, st->name = name; - st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME; - + st->valid |= ZIP_STAT_INDEX | ZIP_STAT_NAME; + return 0; diff --git a/src/Common/libzip/zip_stat_init.c b/src/Common/libzip/zip_stat_init.c index 6b7d6337..0be51381 100644 --- a/src/Common/libzip/zip_stat_init.c +++ b/src/Common/libzip/zip_stat_init.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -39,4 +39,3 @@ ZIP_EXTERN void -zip_stat_init(zip_stat_t *st) -{ +zip_stat_init(zip_stat_t *st) { st->valid = 0; @@ -54,31 +53,30 @@ zip_stat_init(zip_stat_t *st) int -_zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error) -{ +_zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error) { /* name is not merged, since zip_stat_t doesn't own it, and src may not be valid as long as dst */ if (src->valid & ZIP_STAT_INDEX) { - dst->index = src->index; + dst->index = src->index; } if (src->valid & ZIP_STAT_SIZE) { - dst->size = src->size; + dst->size = src->size; } if (src->valid & ZIP_STAT_COMP_SIZE) { - dst->comp_size = src->comp_size; + dst->comp_size = src->comp_size; } if (src->valid & ZIP_STAT_MTIME) { - dst->mtime = src->mtime; + dst->mtime = src->mtime; } if (src->valid & ZIP_STAT_CRC) { - dst->crc = src->crc; + dst->crc = src->crc; } if (src->valid & ZIP_STAT_COMP_METHOD) { - dst->comp_method = src->comp_method; + dst->comp_method = src->comp_method; } if (src->valid & ZIP_STAT_ENCRYPTION_METHOD) { - dst->encryption_method = src->encryption_method; + dst->encryption_method = src->encryption_method; } if (src->valid & ZIP_STAT_FLAGS) { - dst->flags = src->flags; + dst->flags = src->flags; } dst->valid |= src->valid; - + return 0; diff --git a/src/Common/libzip/zip_strerror.c b/src/Common/libzip/zip_strerror.c index 98c4f6b1..9e6e86cd 100644 --- a/src/Common/libzip/zip_strerror.c +++ b/src/Common/libzip/zip_strerror.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -38,4 +38,3 @@ ZIP_EXTERN const char * -zip_strerror(zip_t *za) -{ +zip_strerror(zip_t *za) { return zip_error_strerror(&za->error); diff --git a/src/Common/libzip/zip_string.c b/src/Common/libzip/zip_string.c index 307a425f..293766c1 100644 --- a/src/Common/libzip/zip_string.c +++ b/src/Common/libzip/zip_string.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,9 +41,8 @@ zip_uint32_t -_zip_string_crc32(const zip_string_t *s) -{ +_zip_string_crc32(const zip_string_t *s) { zip_uint32_t crc; - + crc = (zip_uint32_t)crc32(0L, Z_NULL, 0); - if (s != NULL) + if (s != NULL) crc = (zip_uint32_t)crc32(crc, s->raw, s->length); @@ -55,4 +54,3 @@ _zip_string_crc32(const zip_string_t *s) int -_zip_string_equal(const zip_string_t *a, const zip_string_t *b) -{ +_zip_string_equal(const zip_string_t *a, const zip_string_t *b) { if (a == NULL || b == NULL) @@ -70,4 +68,3 @@ _zip_string_equal(const zip_string_t *a, const zip_string_t *b) void -_zip_string_free(zip_string_t *s) -{ +_zip_string_free(zip_string_t *s) { if (s == NULL) @@ -82,4 +79,3 @@ _zip_string_free(zip_string_t *s) const zip_uint8_t * -_zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip_error_t *error) -{ +_zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip_error_t *error) { static const zip_uint8_t empty[1] = ""; @@ -97,8 +93,5 @@ _zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip - if (((flags & ZIP_FL_ENC_STRICT) - && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) - || (string->encoding == ZIP_ENCODING_CP437)) { + if (((flags & ZIP_FL_ENC_STRICT) && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) || (string->encoding == ZIP_ENCODING_CP437)) { if (string->converted == NULL) { - if ((string->converted=_zip_cp437_to_utf8(string->raw, string->length, - &string->converted_length, error)) == NULL) + if ((string->converted = _zip_cp437_to_utf8(string->raw, string->length, &string->converted_length, error)) == NULL) return NULL; @@ -110,3 +103,3 @@ _zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip } - + if (lenp) @@ -118,4 +111,3 @@ _zip_string_get(zip_string_t *string, zip_uint32_t *lenp, zip_flags_t flags, zip zip_uint16_t -_zip_string_length(const zip_string_t *s) -{ +_zip_string_length(const zip_string_t *s) { if (s == NULL) @@ -128,7 +120,6 @@ _zip_string_length(const zip_string_t *s) zip_string_t * -_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error) -{ +_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error) { zip_string_t *s; zip_encoding_type_t expected_encoding; - + if (length == 0) @@ -150,4 +141,4 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, } - - if ((s=(zip_string_t *)malloc(sizeof(*s))) == NULL) { + + if ((s = (zip_string_t *)malloc(sizeof(*s))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -156,3 +147,3 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, - if ((s->raw=(zip_uint8_t *)malloc((size_t)(length+1))) == NULL) { + if ((s->raw = (zip_uint8_t *)malloc((size_t)(length + 1))) == NULL) { free(s); @@ -175,3 +166,3 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, } - + return s; @@ -181,7 +172,6 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, int -_zip_string_write(zip_t *za, const zip_string_t *s) -{ +_zip_string_write(zip_t *za, const zip_string_t *s) { if (s == NULL) return 0; - + return _zip_write(za, s->raw, s->length); diff --git a/src/Common/libzip/zip_unchange.c b/src/Common/libzip/zip_unchange.c index 4a3d6426..b0bd0787 100644 --- a/src/Common/libzip/zip_unchange.c +++ b/src/Common/libzip/zip_unchange.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN int -zip_unchange(zip_t *za, zip_uint64_t idx) -{ +zip_unchange(zip_t *za, zip_uint64_t idx) { return _zip_unchange(za, idx, 0); @@ -47,7 +46,6 @@ zip_unchange(zip_t *za, zip_uint64_t idx) int -_zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) -{ +_zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) { zip_int64_t i; const char *orig_name, *changed_name; - + if (idx >= za->nentry) { @@ -59,3 +57,3 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) if (za->entry[idx].orig != NULL) { - if ((orig_name=_zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) { + if ((orig_name = _zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) { return -1; @@ -72,4 +70,4 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) } - - if ((changed_name=_zip_get_name(za, idx, 0, &za->error)) == NULL) { + + if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) { return -1; @@ -91,3 +89,3 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) - _zip_unchange_data(za->entry+idx); + _zip_unchange_data(za->entry + idx); diff --git a/src/Common/libzip/zip_unchange_all.c b/src/Common/libzip/zip_unchange_all.c index 2221d6cb..165064be 100644 --- a/src/Common/libzip/zip_unchange_all.c +++ b/src/Common/libzip/zip_unchange_all.c @@ -2,3 +2,3 @@ zip_unchange.c -- undo changes to all files in zip archive - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN int -zip_unchange_all(zip_t *za) -{ +zip_unchange_all(zip_t *za) { int ret; @@ -45,6 +44,8 @@ zip_unchange_all(zip_t *za) - _zip_hash_revert(za->names); - + if (!_zip_hash_revert(za->names, &za->error)) { + return -1; + } + ret = 0; - for (i=0; i<za->nentry; i++) + for (i = 0; i < za->nentry; i++) ret |= _zip_unchange(za, i, 1); diff --git a/src/Common/libzip/zip_unchange_archive.c b/src/Common/libzip/zip_unchange_archive.c index 920255cc..f70dba95 100644 --- a/src/Common/libzip/zip_unchange_archive.c +++ b/src/Common/libzip/zip_unchange_archive.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -40,4 +40,3 @@ ZIP_EXTERN int -zip_unchange_archive(zip_t *za) -{ +zip_unchange_archive(zip_t *za) { if (za->comment_changed) { @@ -47,3 +46,3 @@ zip_unchange_archive(zip_t *za) } - + za->ch_flags = za->flags; diff --git a/src/Common/libzip/zip_unchange_data.c b/src/Common/libzip/zip_unchange_data.c index 839d9a3c..1addaa85 100644 --- a/src/Common/libzip/zip_unchange_data.c +++ b/src/Common/libzip/zip_unchange_data.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,4 +37,3 @@ void -_zip_unchange_data(zip_entry_t *ze) -{ +_zip_unchange_data(zip_entry_t *ze) { if (ze->source) { @@ -54,2 +53 @@ _zip_unchange_data(zip_entry_t *ze) } - diff --git a/src/Common/libzip/zip_utf-8.c b/src/Common/libzip/zip_utf-8.c index f38eea04..8f02f88a 100644 --- a/src/Common/libzip/zip_utf-8.c +++ b/src/Common/libzip/zip_utf-8.c @@ -19,3 +19,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -41,73 +41,56 @@ static const zip_uint16_t _cp437_to_unicode[256] = { /* 0x00 - 0x0F */ - 0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, - 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + 0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, /* 0x10 - 0x1F */ - 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, - 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, /* 0x20 - 0x2F */ - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, /* 0x30 - 0x3F */ - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, /* 0x40 - 0x4F */ - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, /* 0x50 - 0x5F */ - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, /* 0x60 - 0x6F */ - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, /* 0x70 - 0x7F */ - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, /* 0x80 - 0x8F */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, - 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, /* 0x90 - 0x9F */ - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, - 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, /* 0xA0 - 0xAF */ - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, - 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, /* 0xB0 - 0xBF */ - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, - 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, /* 0xC0 - 0xCF */ - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, - 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, /* 0xD0 - 0xDF */ - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, - 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, /* 0xE0 - 0xEF */ - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, - 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, /* 0xF0 - 0xFF */ - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, - 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; - -#define UTF_8_LEN_2_MASK 0xe0 -#define UTF_8_LEN_2_MATCH 0xc0 -#define UTF_8_LEN_3_MASK 0xf0 -#define UTF_8_LEN_3_MATCH 0xe0 -#define UTF_8_LEN_4_MASK 0xf8 -#define UTF_8_LEN_4_MATCH 0xf0 -#define UTF_8_CONTINUE_MASK 0xc0 + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0}; + +#define UTF_8_LEN_2_MASK 0xe0 +#define UTF_8_LEN_2_MATCH 0xc0 +#define UTF_8_LEN_3_MASK 0xf0 +#define UTF_8_LEN_3_MATCH 0xe0 +#define UTF_8_LEN_4_MASK 0xf8 +#define UTF_8_LEN_4_MATCH 0xf0 +#define UTF_8_CONTINUE_MASK 0xc0 #define UTF_8_CONTINUE_MATCH 0x80 @@ -116,4 +99,3 @@ static const zip_uint16_t _cp437_to_unicode[256] = { zip_encoding_type_t -_zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) -{ +_zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) { zip_encoding_type_t enc; @@ -131,3 +113,3 @@ _zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) enc = ZIP_ENCODING_ASCII; - for (i=0; i<str->length; i++) { + for (i = 0; i < str->length; i++) { if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t') @@ -152,4 +134,4 @@ _zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding) - for (j=1; j<=ulen; j++) { - if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) { + for (j = 1; j <= ulen; j++) { + if ((name[i + j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) { enc = ZIP_ENCODING_CP437; @@ -172,3 +154,3 @@ done: } - + return enc; @@ -178,4 +160,3 @@ done: static zip_uint32_t -_zip_unicode_to_utf8_len(zip_uint32_t codepoint) -{ +_zip_unicode_to_utf8_len(zip_uint32_t codepoint) { if (codepoint < 0x0080) @@ -191,4 +172,3 @@ _zip_unicode_to_utf8_len(zip_uint32_t codepoint) static zip_uint32_t -_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) -{ +_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) { if (codepoint < 0x0080) { @@ -217,5 +197,3 @@ _zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) zip_uint8_t * -_zip_cp437_to_utf8(const zip_uint8_t * const _cp437buf, zip_uint32_t len, - zip_uint32_t *utf8_lenp, zip_error_t *error) -{ +_zip_cp437_to_utf8(const zip_uint8_t *const _cp437buf, zip_uint32_t len, zip_uint32_t *utf8_lenp, zip_error_t *error) { zip_uint8_t *cp437buf = (zip_uint8_t *)_cp437buf; @@ -231,6 +209,6 @@ _zip_cp437_to_utf8(const zip_uint8_t * const _cp437buf, zip_uint32_t len, buflen = 1; - for (i=0; i<len; i++) + for (i = 0; i < len; i++) buflen += _zip_unicode_to_utf8_len(_cp437_to_unicode[cp437buf[i]]); - if ((utf8buf=(zip_uint8_t*)malloc(buflen)) == NULL) { + if ((utf8buf = (zip_uint8_t *)malloc(buflen)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); @@ -240,9 +218,8 @@ _zip_cp437_to_utf8(const zip_uint8_t * const _cp437buf, zip_uint32_t len, offset = 0; - for (i=0; i<len; i++) - offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]], - utf8buf+offset); + for (i = 0; i < len; i++) + offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]], utf8buf + offset); - utf8buf[buflen-1] = 0; + utf8buf[buflen - 1] = 0; if (utf8_lenp) - *utf8_lenp = buflen-1; + *utf8_lenp = buflen - 1; return utf8buf; diff --git a/src/Common/libzip/zipconf.h b/src/Common/libzip/zipconf.h index 3c506aea..e4224da2 100644 --- a/src/Common/libzip/zipconf.h +++ b/src/Common/libzip/zipconf.h @@ -1 +1,6 @@ +/* + This file was generated automatically by C:\dev\prj\Github\VeraCrypt\src\Common\libzip\make_zip_err_str.sh + from C:\dev\libraries\libzip\build\config.h; make changes there. + */ + #ifndef _HAD_ZIPCONF_H @@ -3,102 +8,21 @@ -/* - zipconf.h -- platform specific include file +extern const char * const _zip_err_str[]; - This file was generated automatically by CMake - based on ../cmake-zipconf.h.in. - */ +extern const int _zip_nerr_str; + +#define N ZIP_ET_NONE +#define S ZIP_ET_SYS +#define Z ZIP_ET_ZLIB -/* #undef HAVE_INTTYPES_H_LIBZIP */ -#define HAVE_STDINT_H_LIBZIP -#define HAVE_SYS_TYPES_H_LIBZIP -#define HAVE___INT8_LIBZIP -#define HAVE_INT8_T_LIBZIP -#define HAVE_UINT8_T_LIBZIP -#define HAVE___INT16_LIBZIP -#define HAVE_INT16_T_LIBZIP -#define HAVE_UINT16_T_LIBZIP -#define HAVE___INT32_LIBZIP -#define HAVE_INT32_T_LIBZIP -#define HAVE_UINT32_T_LIBZIP -#define HAVE___INT64_LIBZIP -#define HAVE_INT64_T_LIBZIP -#define HAVE_UINT64_T_LIBZIP -/* #undef HAVE_SSIZE_T_LIBZIP */ -#define SHORT_LIBZIP 2 -#define INT_LIBZIP 4 -#define LONG_LIBZIP 4 -#define LONG_LONG_LIBZIP 8 +extern const int _zip_err_type[]; -#if defined(HAVE_STDINT_H_LIBZIP) -#include <stdint.h> -#elif defined(HAVE_INTTYPES_H_LIBZIP) -#include <inttypes.h> -#elif defined(HAVE_SYS_TYPES_H_LIBZIP) -#include <sys/types.h> -#endif -#if defined(HAVE_INT8_T_LIBZIP) -typedef int8_t zip_int8_t; -#elif defined(HAVE___INT8_LIBZIP) -typedef __int8 zip_int8_t; -#else typedef signed char zip_int8_t; -#endif -#if defined(HAVE_UINT8_T_LIBZIP) -typedef uint8_t zip_uint8_t; -#elif defined(HAVE___INT8_LIBZIP) -typedef unsigned __int8 zip_uint8_t; -#else typedef unsigned char zip_uint8_t; -#endif -#if defined(HAVE_INT16_T_LIBZIP) -typedef int16_t zip_int16_t; -#elif defined(HAVE___INT16_LIBZIP) -typedef __int16 zip_int16_t; -#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 typedef signed short zip_int16_t; -#endif -#if defined(HAVE_UINT16_T_LIBZIP) -typedef uint16_t zip_uint16_t; -#elif defined(HAVE___INT16_LIBZIP) -typedef unsigned __int16 zip_uint16_t; -#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 typedef unsigned short zip_uint16_t; -#endif -#if defined(HAVE_INT32_T_LIBZIP) -typedef int32_t zip_int32_t; -#elif defined(HAVE___INT32_LIBZIP) -typedef __int32 zip_int32_t; -#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 typedef signed int zip_int32_t; -#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 -typedef signed long zip_int32_t; -#endif -#if defined(HAVE_UINT32_T_LIBZIP) -typedef uint32_t zip_uint32_t; -#elif defined(HAVE___INT32_LIBZIP) -typedef unsigned __int32 zip_uint32_t; -#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 typedef unsigned int zip_uint32_t; -#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 -typedef unsigned long zip_uint32_t; -#endif -#if defined(HAVE_INT64_T_LIBZIP) -typedef int64_t zip_int64_t; -#elif defined(HAVE___INT64_LIBZIP) -typedef __int64 zip_int64_t; -#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 8 -typedef signed long zip_int64_t; -#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 typedef signed long long zip_int64_t; -#endif -#if defined(HAVE_UINT64_T_LIBZIP) -typedef uint64_t zip_uint64_t; -#elif defined(HAVE___INT64_LIBZIP) -typedef unsigned __int64 zip_uint64_t; -#elif defined(LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 -typedef unsigned long zip_uint64_t; -#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 typedef unsigned long long zip_uint64_t; -#endif @@ -121 +45,2 @@ typedef unsigned long long zip_uint64_t; #endif /* zipconf.h */ + diff --git a/src/Common/libzip/zipint.h b/src/Common/libzip/zipint.h index 2c5c6b9b..3c60eced 100644 --- a/src/Common/libzip/zipint.h +++ b/src/Common/libzip/zipint.h @@ -5,3 +5,3 @@ zipint.h -- internal declarations. - Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner @@ -51,16 +51,16 @@ #define CENTRAL_MAGIC "PK\1\2" -#define LOCAL_MAGIC "PK\3\4" -#define EOCD_MAGIC "PK\5\6" -#define DATADES_MAGIC "PK\7\8" +#define LOCAL_MAGIC "PK\3\4" +#define EOCD_MAGIC "PK\5\6" +#define DATADES_MAGIC "PK\7\10" #define EOCD64LOC_MAGIC "PK\6\7" -#define EOCD64_MAGIC "PK\6\6" -#define CDENTRYSIZE 46u -#define LENTRYSIZE 30 -#define MAXCOMLEN 65536 -#define MAXEXTLEN 65536 -#define EOCDLEN 22 -#define EOCD64LOCLEN 20 -#define EOCD64LEN 56 -#define CDBUFSIZE (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN) -#define BUFSIZE 8192 +#define EOCD64_MAGIC "PK\6\6" +#define CDENTRYSIZE 46u +#define LENTRYSIZE 30 +#define MAXCOMLEN 65536 +#define MAXEXTLEN 65536 +#define EOCDLEN 22 +#define EOCD64LOCLEN 20 +#define EOCD64LEN 56 +#define CDBUFSIZE (MAXCOMLEN + EOCDLEN + EOCD64LOCLEN) +#define BUFSIZE 8192 #define EFZIP64SIZE 28 @@ -68,22 +68,30 @@ -#define ZIP_CM_REPLACED_DEFAULT (-2) -#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */ +#define ZIP_CM_REPLACED_DEFAULT (-2) +#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */ -#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) +#define WINZIP_AES_PASSWORD_VERIFY_LENGTH 2 +#define WINZIP_AES_MAX_HEADER_LENGTH (16 + WINZIP_AES_PASSWORD_VERIFY_LENGTH) +#define AES_BLOCK_SIZE 16 +#define HMAC_LENGTH 10 +#define SHA1_LENGTH 20 +#define SALT_LENGTH(method) ((method) == ZIP_EM_AES_128 ? 8 : ((method) == ZIP_EM_AES_192 ? 12 : 16)) -#define ZIP_EF_UTF_8_COMMENT 0x6375 -#define ZIP_EF_UTF_8_NAME 0x7075 -#define ZIP_EF_WINZIP_AES 0x9901 -#define ZIP_EF_ZIP64 0x0001 +#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) +#define ZIP_CM_ACTUAL(x) ((zip_uint16_t)(ZIP_CM_IS_DEFAULT(x) ? ZIP_CM_DEFLATE : (x))) -#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_WINZIP_AES || (id) == ZIP_EF_ZIP64) +#define ZIP_EF_UTF_8_COMMENT 0x6375 +#define ZIP_EF_UTF_8_NAME 0x7075 +#define ZIP_EF_WINZIP_AES 0x9901 +#define ZIP_EF_ZIP64 0x0001 + +#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_WINZIP_AES || (id) == ZIP_EF_ZIP64) /* according to unzip-6.0's zipinfo.c, this corresponds to a regular file with rw permissions for everyone */ -#define ZIP_EXT_ATTRIB_DEFAULT (0100666u<<16) +#define ZIP_EXT_ATTRIB_DEFAULT (0100666u << 16) /* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */ -#define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u<<16) +#define ZIP_EXT_ATTRIB_DEFAULT_DIR (0040777u << 16) -#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -94,13 +102,50 @@ -#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ -#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ - +#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 *); -zip_compression_implementation _zip_get_compression_implementation(zip_int32_t method, int operation); zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t method, int operation); +// clang-format off +enum zip_compression_status { + ZIP_COMPRESSION_OK, + ZIP_COMPRESSION_END, + ZIP_COMPRESSION_ERROR, + ZIP_COMPRESSION_NEED_DATA +}; +// clang-format on +typedef enum zip_compression_status zip_compression_status_t; + +struct zip_compression_algorithm { + /* called once to create new context */ + void *(*allocate)(zip_uint16_t method, int compression_flags, zip_error_t *error); + /* called once to free context */ + void (*deallocate)(void *ctx); + + /* get compression specific general purpose bitflags */ + int (*compression_flags)(void *ctx); + /* start processing */ + bool (*start)(void *ctx); + /* stop processing */ + bool (*end)(void *ctx); + + /* provide new input data, remains valid until next call to input or end */ + bool (*input)(void *ctx, zip_uint8_t *data, zip_uint64_t length); + + /* all input data has been provided */ + void (*end_of_input)(void *ctx); + + /* process input data, writing to data, which has room for length bytes, update length to number of bytes written */ + zip_compression_status_t (*process)(void *ctx, zip_uint8_t *data, zip_uint64_t *length); +}; +typedef struct zip_compression_algorithm zip_compression_algorithm_t; + +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; + +bool zip_compression_method_supported(zip_int32_t method, bool compress); @@ -115,4 +160,5 @@ const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, in typedef zip_int64_t (*zip_source_layered_callback)(zip_source_t *, void *, void *, zip_uint64_t, enum zip_source_cmd); +zip_source_t *zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t cm, int compression_flags); zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int); -zip_source_t *zip_source_deflate(zip_t *, zip_source_t *, zip_int32_t, int); +zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm); zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *); @@ -133,6 +179,6 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; -#define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ -#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ -#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ -#define ZIP_GPBF_ENCODING_UTF_8 0x0800 /* file name encoding is UTF-8 */ +#define ZIP_GPBF_ENCRYPTED 0x0001u /* is encrypted */ +#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008u /* crc/size after file data */ +#define ZIP_GPBF_STRONG_ENCRYPTION 0x0040u /* uses strong encryption */ +#define ZIP_GPBF_ENCODING_UTF_8 0x0800u /* file name encoding is UTF-8 */ @@ -140,9 +186,9 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; /* extra fields */ -#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */ -#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ -#define ZIP_EF_BOTH (ZIP_EF_LOCAL|ZIP_EF_CENTRAL) /* include in both */ +#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */ +#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ +#define ZIP_EF_BOTH (ZIP_EF_LOCAL | ZIP_EF_CENTRAL) /* include in both */ -#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ +#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ -#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS|ZIP_FL_ENC_CP437|ZIP_FL_ENC_UTF_8) +#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS | ZIP_FL_ENC_CP437 | ZIP_FL_ENC_UTF_8) @@ -151,8 +197,8 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; enum zip_encoding_type { - ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ - ZIP_ENCODING_ASCII, /* plain ASCII */ - ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */ - ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */ - ZIP_ENCODING_CP437, /* Code Page 437 */ - ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */ + ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ + ZIP_ENCODING_ASCII, /* plain ASCII */ + ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */ + ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */ + ZIP_ENCODING_CP437, /* Code Page 437 */ + ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */ }; @@ -161,7 +207,4 @@ typedef enum zip_encoding_type zip_encoding_type_t; -#ifndef ZIP_HASH_TABLE_SIZE -#define ZIP_HASH_TABLE_SIZE 8192 -#endif - struct zip_hash; +struct zip_progress; @@ -174,2 +217,3 @@ typedef struct zip_buffer zip_buffer_t; typedef struct zip_hash zip_hash_t; +typedef struct zip_progress zip_progress_t; @@ -178,26 +222,26 @@ typedef struct zip_hash zip_hash_t; struct zip { - zip_source_t *src; /* data source for archive */ - unsigned int open_flags; /* flags passed to zip_open */ - zip_error_t error; /* error information */ + zip_source_t *src; /* data source for archive */ + unsigned int open_flags; /* flags passed to zip_open */ + zip_error_t error; /* error information */ - unsigned int flags; /* archive global flags */ - unsigned int ch_flags; /* changed archive global flags */ + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ - char *default_password; /* password used when no other supplied */ + char *default_password; /* password used when no other supplied */ - zip_string_t *comment_orig; /* archive comment */ - zip_string_t *comment_changes; /* changed archive comment */ - bool comment_changed; /* whether archive comment was changed */ + zip_string_t *comment_orig; /* archive comment */ + zip_string_t *comment_changes; /* changed archive comment */ + bool comment_changed; /* whether archive comment was changed */ - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - zip_entry_t *entry; /* entries */ + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ + zip_entry_t *entry; /* entries */ - unsigned int nopen_source; /* number of open sources using archive */ - unsigned int nopen_source_alloc; /* number of sources allocated */ - zip_source_t **open_source; /* open sources using archive */ + unsigned int nopen_source; /* number of open sources using archive */ + unsigned int nopen_source_alloc; /* number of sources allocated */ + zip_source_t **open_source; /* open sources using archive */ - zip_hash_t *names; /* hash table for name lookup */ + zip_hash_t *names; /* hash table for name lookup */ - zip_progress_callback_t progress_callback; /* progress callback for zip_close() */ + zip_progress_t *progress; /* progress callback for zip_close() */ }; @@ -207,6 +251,6 @@ struct zip { struct zip_file { - zip_t *za; /* zip archive containing this file */ - zip_error_t error; /* error information */ + zip_t *za; /* zip archive containing this file */ + zip_error_t error; /* error information */ bool eof; - zip_source_t *src; /* data source */ + zip_source_t *src; /* data source */ }; @@ -215,11 +259,11 @@ struct zip_file { -#define ZIP_DIRENT_COMP_METHOD 0x0001u -#define ZIP_DIRENT_FILENAME 0x0002u -#define ZIP_DIRENT_COMMENT 0x0004u -#define ZIP_DIRENT_EXTRA_FIELD 0x0008u -#define ZIP_DIRENT_ATTRIBUTES 0x0010u -#define ZIP_DIRENT_LAST_MOD 0x0020u -#define ZIP_DIRENT_ENCRYPTION_METHOD 0x0040u -#define ZIP_DIRENT_PASSWORD 0x0080u -#define ZIP_DIRENT_ALL ZIP_UINT32_MAX +#define ZIP_DIRENT_COMP_METHOD 0x0001u +#define ZIP_DIRENT_FILENAME 0x0002u +#define ZIP_DIRENT_COMMENT 0x0004u +#define ZIP_DIRENT_EXTRA_FIELD 0x0008u +#define ZIP_DIRENT_ATTRIBUTES 0x0010u +#define ZIP_DIRENT_LAST_MOD 0x0020u +#define ZIP_DIRENT_ENCRYPTION_METHOD 0x0040u +#define ZIP_DIRENT_PASSWORD 0x0080u +#define ZIP_DIRENT_ALL ZIP_UINT32_MAX @@ -227,25 +271,26 @@ struct zip_dirent { zip_uint32_t changed; - 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 */ - - bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */ - - zip_uint16_t version_madeby; /* (c) version of creator */ - zip_uint16_t version_needed; /* (cl) version needed to extract */ - zip_uint16_t bitflags; /* (cl) general purpose bit flag */ - zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ - time_t last_mod; /* (cl) time of last modification */ - zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */ - zip_uint64_t comp_size; /* (cl) size of compressed data */ - zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */ - zip_string_t *filename; /* (cl) file name (NUL-terminated) */ - zip_extra_field_t *extra_fields; /* (cl) extra fields, parsed */ - zip_string_t *comment; /* (c) file comment */ - zip_uint32_t disk_number; /* (c) disk number start */ - zip_uint16_t int_attrib; /* (c) internal file attributes */ - zip_uint32_t ext_attrib; /* (c) external file attributes */ - zip_uint64_t offset; /* (c) offset of local header */ - - zip_uint16_t encryption_method; /* encryption method, computed from other fields */ - char *password; /* file specific encryption password */ + 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 */ + + bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */ + + zip_uint16_t version_madeby; /* (c) version of creator */ + zip_uint16_t version_needed; /* (cl) version needed to extract */ + zip_uint16_t bitflags; /* (cl) general purpose bit flag */ + zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ + time_t last_mod; /* (cl) time of last modification */ + zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */ + zip_uint64_t comp_size; /* (cl) size of compressed data */ + zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */ + zip_string_t *filename; /* (cl) file name (NUL-terminated) */ + zip_extra_field_t *extra_fields; /* (cl) extra fields, parsed */ + zip_string_t *comment; /* (c) file comment */ + zip_uint32_t disk_number; /* (c) disk number start */ + zip_uint16_t int_attrib; /* (c) internal file attributes */ + zip_uint32_t ext_attrib; /* (c) external file attributes */ + zip_uint64_t offset; /* (c) offset of local header */ + + zip_uint16_t compression_level; /* level of compression to use (never valid in orig) */ + zip_uint16_t encryption_method; /* encryption method, computed from other fields */ + char *password; /* file specific encryption password */ }; @@ -255,10 +300,10 @@ struct zip_dirent { struct zip_cdir { - zip_entry_t *entry; /* directory entries */ - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - - zip_uint64_t size; /* size of central directory */ - zip_uint64_t offset; /* offset of central directory in file */ - zip_string_t *comment; /* zip archive comment */ - bool is_zip64; /* central directory in zip64 format */ + zip_entry_t *entry; /* directory entries */ + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ + + zip_uint64_t size; /* size of central directory */ + zip_uint64_t offset; /* offset of central directory in file */ + zip_string_t *comment; /* zip archive comment */ + bool is_zip64; /* central directory in zip64 format */ }; @@ -267,5 +312,5 @@ struct zip_extra_field { zip_extra_field_t *next; - zip_flags_t flags; /* in local/central header */ - zip_uint16_t id; /* header id */ - zip_uint16_t size; /* data size */ + zip_flags_t flags; /* in local/central header */ + zip_uint16_t id; /* header id */ + zip_uint16_t size; /* data size */ zip_uint8_t *data; @@ -274,6 +319,6 @@ struct zip_extra_field { enum zip_source_write_state { - ZIP_SOURCE_WRITE_CLOSED, /* write is not in progress */ - ZIP_SOURCE_WRITE_OPEN, /* write is in progress */ - ZIP_SOURCE_WRITE_FAILED, /* commit failed, only rollback allowed */ - ZIP_SOURCE_WRITE_REMOVED /* file was removed */ + ZIP_SOURCE_WRITE_CLOSED, /* write is not in progress */ + ZIP_SOURCE_WRITE_OPEN, /* write is in progress */ + ZIP_SOURCE_WRITE_FAILED, /* commit failed, only rollback allowed */ + ZIP_SOURCE_WRITE_REMOVED /* file was removed */ }; @@ -289,9 +334,10 @@ struct zip_source { zip_error_t error; - zip_int64_t supports; /* supported commands */ - unsigned int open_count; /* number of times source was opened (directly or as lower layer) */ - zip_source_write_state_t write_state; /* whether source is open for writing */ - bool source_closed; /* set if source archive is closed */ - zip_t *source_archive; /* zip archive we're reading from, NULL if not from archive */ + zip_int64_t supports; /* supported commands */ + unsigned int open_count; /* number of times source was opened (directly or as lower layer) */ + zip_source_write_state_t write_state; /* whether source is open for writing */ + bool source_closed; /* set if source archive is closed */ + zip_t *source_archive; /* zip archive we're reading from, NULL if not from archive */ unsigned int refcount; - bool eof; /* EOF reached */ + bool eof; /* EOF reached */ + bool had_read_error; /* a previous ZIP_SOURCE_READ reported an error */ }; @@ -300,3 +346,3 @@ struct zip_source { #define ZIP_SOURCE_IS_OPEN_WRITING(src) ((src)->write_state == ZIP_SOURCE_WRITE_OPEN) -#define ZIP_SOURCE_IS_LAYERED(src) ((src)->src != NULL) +#define ZIP_SOURCE_IS_LAYERED(src) ((src)->src != NULL) @@ -315,7 +361,7 @@ struct zip_entry { struct zip_string { - zip_uint8_t *raw; /* raw string */ - zip_uint16_t length; /* length of raw string */ - enum zip_encoding_type encoding; /* autorecognized encoding */ - zip_uint8_t *converted; /* autoconverted string */ - zip_uint32_t converted_length; /* length of converted */ + zip_uint8_t *raw; /* raw string */ + zip_uint16_t length; /* length of raw string */ + enum zip_encoding_type encoding; /* autorecognized encoding */ + zip_uint8_t *converted; /* autoconverted string */ + zip_uint32_t converted_length; /* length of converted */ }; @@ -338,3 +384,3 @@ struct zip_filelist { zip_uint64_t idx; -/* TODO const char *name; */ + /* TODO const char *name; */ }; @@ -343,4 +389,6 @@ typedef struct zip_filelist zip_filelist_t; +struct _zip_winzip_aes; +typedef struct _zip_winzip_aes zip_winzip_aes_t; -extern const char * const _zip_err_str[]; +extern const char *const _zip_err_str[]; extern const int _zip_nerr_str; @@ -348,10 +396,10 @@ extern const int _zip_err_type[]; -#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b)) -#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f))) +#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f))) +#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL) +#define ZIP_ENTRY_HAS_CHANGES(e) (ZIP_ENTRY_DATA_CHANGED(e) || (e)->deleted || ZIP_ENTRY_CHANGED((e), ZIP_DIRENT_ALL)) -#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL) - -#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) +#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) @@ -364,2 +412,3 @@ extern const int _zip_err_type[]; #else +#include <string.h> #define _zip_crypto_clear(b, l) memset((b), 0, (l)) @@ -409,2 +458,3 @@ zip_dirent_t *_zip_dirent_new(void); zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error); +void _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64); zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *); @@ -436,2 +486,3 @@ int _zip_file_extra_field_prepare_for_change(zip_t *, zip_uint64_t); int _zip_file_fillbuf(void *, size_t, zip_file_t *); +zip_uint64_t _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error); zip_uint64_t _zip_file_get_offset(const zip_t *, zip_uint64_t, zip_error_t *); @@ -443,3 +494,3 @@ zip_dirent_t *_zip_get_dirent(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *) enum zip_encoding_type _zip_guess_encoding(zip_string_t *, enum zip_encoding_type); -zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t * const, zip_uint32_t, zip_uint32_t *, zip_error_t *); +zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t *const, zip_uint32_t, zip_uint32_t *, zip_error_t *); @@ -449,4 +500,5 @@ void _zip_hash_free(zip_hash_t *hash); zip_int64_t _zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error); -zip_hash_t *_zip_hash_new(zip_uint16_t hash_size, zip_error_t *error); -void _zip_hash_revert(zip_hash_t *hash); +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); @@ -454,3 +506,10 @@ zip_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *); -bool zip_random(zip_uint8_t *buffer, zip_uint16_t length); +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); + +ZIP_EXTERN bool zip_random(zip_uint8_t *buffer, zip_uint16_t length); @@ -468,7 +527,8 @@ 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); -void _zip_source_invalidate(zip_source_t *src); +zip_int8_t zip_source_get_compression_flags(zip_source_t *); bool _zip_source_had_error(zip_source_t *); +void _zip_source_invalidate(zip_source_t *src); zip_source_t *_zip_source_new(zip_error_t *error); int _zip_source_set_source_archive(zip_source_t *, zip_t *); -zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_error_t *error); +zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error); zip_source_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *); @@ -483,2 +543,7 @@ zip_string_t *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zi int _zip_string_write(zip_t *za, const zip_string_t *string); +bool _zip_winzip_aes_decrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); +bool _zip_winzip_aes_encrypt(zip_winzip_aes_t *ctx, zip_uint8_t *data, zip_uint64_t length); +bool _zip_winzip_aes_finish(zip_winzip_aes_t *ctx, zip_uint8_t *hmac); +void _zip_winzip_aes_free(zip_winzip_aes_t *ctx); +zip_winzip_aes_t *_zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, const zip_uint8_t *salt, zip_uint16_t key_size, zip_uint8_t *password_verify, zip_error_t *error); diff --git a/src/Common/libzip/zipwin32.h b/src/Common/libzip/zipwin32.h index 60f8d0cf..d2c5d827 100644 --- a/src/Common/libzip/zipwin32.h +++ b/src/Common/libzip/zipwin32.h @@ -22,3 +22,3 @@ written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS @@ -37,3 +37,6 @@ /* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */ +#if !defined(MS_UWP) && !defined(_WIN32_WINNT) #define _WIN32_WINNT 0x0501 +#endif + #include <windows.h> @@ -45,3 +48,3 @@ struct _zip_source_win32_file_ops; struct _zip_source_win32_read_file { - zip_error_t error; /* last error information */ + zip_error_t error; /* last error information */ zip_int64_t supports; @@ -52,13 +55,13 @@ struct _zip_source_win32_read_file { /* reading */ - void *fname; /* name of file to read from - ANSI (char *) or Unicode (wchar_t *) */ - void *h; /* HANDLE for file to read from */ - int closep; /* whether to close f on ZIP_CMD_FREE */ - struct zip_stat st; /* stat information passed in */ - zip_uint64_t start; /* start offset of data to read */ - zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */ - zip_uint64_t current; /* current offset */ + void *fname; /* name of file to read from - ANSI (char *) or Unicode (wchar_t *) */ + void *h; /* HANDLE for file to read from */ + int closep; /* whether to close f on ZIP_CMD_FREE */ + struct zip_stat st; /* stat information passed in */ + zip_uint64_t start; /* start offset of data to read */ + zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */ + zip_uint64_t current; /* current offset */ /* writing */ - void *tmpname; /* name of temp file - ANSI (char *) or Unicode (wchar_t *) */ - void *hout; /* HANDLE for output file */ + void *tmpname; /* name of temp file - ANSI (char *) or Unicode (wchar_t *) */ + void *hout; /* HANDLE for output file */ }; |