VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/libzip
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/libzip')
-rw-r--r--src/Common/libzip/LICENSE31
-rw-r--r--src/Common/libzip/NEWS.md159
-rw-r--r--src/Common/libzip/compat.h181
-rw-r--r--src/Common/libzip/config.h72
-rw-r--r--src/Common/libzip/mkstemp.c150
-rw-r--r--src/Common/libzip/zip.h422
-rw-r--r--src/Common/libzip/zip_add.c50
-rw-r--r--src/Common/libzip/zip_add_dir.c45
-rw-r--r--src/Common/libzip/zip_add_entry.c81
-rw-r--r--src/Common/libzip/zip_buffer.c321
-rw-r--r--src/Common/libzip/zip_close.c492
-rw-r--r--src/Common/libzip/zip_delete.c70
-rw-r--r--src/Common/libzip/zip_dir_add.c93
-rw-r--r--src/Common/libzip/zip_dirent.c913
-rw-r--r--src/Common/libzip/zip_discard.c79
-rw-r--r--src/Common/libzip/zip_entry.c53
-rw-r--r--src/Common/libzip/zip_err_str.c80
-rw-r--r--src/Common/libzip/zip_error.c155
-rw-r--r--src/Common/libzip/zip_error_clear.c45
-rw-r--r--src/Common/libzip/zip_error_get.c57
-rw-r--r--src/Common/libzip/zip_error_get_sys_type.c45
-rw-r--r--src/Common/libzip/zip_error_strerror.c87
-rw-r--r--src/Common/libzip/zip_error_to_str.c68
-rw-r--r--src/Common/libzip/zip_extra_field.c438
-rw-r--r--src/Common/libzip/zip_extra_field_api.c366
-rw-r--r--src/Common/libzip/zip_fclose.c55
-rw-r--r--src/Common/libzip/zip_fdopen.c85
-rw-r--r--src/Common/libzip/zip_file_add.c53
-rw-r--r--src/Common/libzip/zip_file_error_clear.c45
-rw-r--r--src/Common/libzip/zip_file_error_get.c42
-rw-r--r--src/Common/libzip/zip_file_get_comment.c56
-rw-r--r--src/Common/libzip/zip_file_get_external_attributes.c51
-rw-r--r--src/Common/libzip/zip_file_get_offset.c73
-rw-r--r--src/Common/libzip/zip_file_rename.c68
-rw-r--r--src/Common/libzip/zip_file_replace.c108
-rw-r--r--src/Common/libzip/zip_file_set_comment.c103
-rw-r--r--src/Common/libzip/zip_file_set_external_attributes.c83
-rw-r--r--src/Common/libzip/zip_file_set_mtime.c74
-rw-r--r--src/Common/libzip/zip_file_strerror.c42
-rw-r--r--src/Common/libzip/zip_filerange_crc.c76
-rw-r--r--src/Common/libzip/zip_fopen.c47
-rw-r--r--src/Common/libzip/zip_fopen_encrypted.c47
-rw-r--r--src/Common/libzip/zip_fopen_index.c45
-rw-r--r--src/Common/libzip/zip_fopen_index_encrypted.c86
-rw-r--r--src/Common/libzip/zip_fread.c63
-rw-r--r--src/Common/libzip/zip_get_archive_comment.c59
-rw-r--r--src/Common/libzip/zip_get_archive_flag.c46
-rw-r--r--src/Common/libzip/zip_get_compression_implementation.c44
-rw-r--r--src/Common/libzip/zip_get_encryption_implementation.c44
-rw-r--r--src/Common/libzip/zip_get_file_comment.c51
-rw-r--r--src/Common/libzip/zip_get_name.c60
-rw-r--r--src/Common/libzip/zip_get_num_entries.c53
-rw-r--r--src/Common/libzip/zip_get_num_files.c52
-rw-r--r--src/Common/libzip/zip_hash.c267
-rw-r--r--src/Common/libzip/zip_io_util.c138
-rw-r--r--src/Common/libzip/zip_memdup.c57
-rw-r--r--src/Common/libzip/zip_name_locate.c94
-rw-r--r--src/Common/libzip/zip_new.c74
-rw-r--r--src/Common/libzip/zip_open.c853
-rw-r--r--src/Common/libzip/zip_rename.c45
-rw-r--r--src/Common/libzip/zip_replace.c43
-rw-r--r--src/Common/libzip/zip_set_archive_comment.c82
-rw-r--r--src/Common/libzip/zip_set_archive_flag.c67
-rw-r--r--src/Common/libzip/zip_set_default_password.c59
-rw-r--r--src/Common/libzip/zip_set_file_comment.c49
-rw-r--r--src/Common/libzip/zip_set_file_compression.c87
-rw-r--r--src/Common/libzip/zip_set_name.c158
-rw-r--r--src/Common/libzip/zip_source_begin_write.c53
-rw-r--r--src/Common/libzip/zip_source_buffer.c435
-rw-r--r--src/Common/libzip/zip_source_call.c69
-rw-r--r--src/Common/libzip/zip_source_close.c58
-rw-r--r--src/Common/libzip/zip_source_commit_write.c64
-rw-r--r--src/Common/libzip/zip_source_crc.c202
-rw-r--r--src/Common/libzip/zip_source_deflate.c415
-rw-r--r--src/Common/libzip/zip_source_error.c42
-rw-r--r--src/Common/libzip/zip_source_file.c63
-rw-r--r--src/Common/libzip/zip_source_filep.c503
-rw-r--r--src/Common/libzip/zip_source_free.c72
-rw-r--r--src/Common/libzip/zip_source_function.c99
-rw-r--r--src/Common/libzip/zip_source_is_deleted.c42
-rw-r--r--src/Common/libzip/zip_source_layered.c69
-rw-r--r--src/Common/libzip/zip_source_open.c73
-rw-r--r--src/Common/libzip/zip_source_pkware.c226
-rw-r--r--src/Common/libzip/zip_source_read.c50
-rw-r--r--src/Common/libzip/zip_source_remove.c61
-rw-r--r--src/Common/libzip/zip_source_rollback_write.c47
-rw-r--r--src/Common/libzip/zip_source_seek.c92
-rw-r--r--src/Common/libzip/zip_source_seek_write.c52
-rw-r--r--src/Common/libzip/zip_source_stat.c63
-rw-r--r--src/Common/libzip/zip_source_supports.c68
-rw-r--r--src/Common/libzip/zip_source_tell.c50
-rw-r--r--src/Common/libzip/zip_source_tell_write.c47
-rw-r--r--src/Common/libzip/zip_source_win32a.c124
-rw-r--r--src/Common/libzip/zip_source_win32handle.c607
-rw-r--r--src/Common/libzip/zip_source_win32utf8.c79
-rw-r--r--src/Common/libzip/zip_source_win32w.c124
-rw-r--r--src/Common/libzip/zip_source_window.c253
-rw-r--r--src/Common/libzip/zip_source_write.c47
-rw-r--r--src/Common/libzip/zip_source_zip.c59
-rw-r--r--src/Common/libzip/zip_source_zip_new.c173
-rw-r--r--src/Common/libzip/zip_stat.c47
-rw-r--r--src/Common/libzip/zip_stat_index.c86
-rw-r--r--src/Common/libzip/zip_stat_init.c85
-rw-r--r--src/Common/libzip/zip_strerror.c42
-rw-r--r--src/Common/libzip/zip_string.c188
-rw-r--r--src/Common/libzip/zip_unchange.c95
-rw-r--r--src/Common/libzip/zip_unchange_all.c55
-rw-r--r--src/Common/libzip/zip_unchange_archive.c52
-rw-r--r--src/Common/libzip/zip_unchange_data.c55
-rw-r--r--src/Common/libzip/zip_utf-8.c249
-rw-r--r--src/Common/libzip/zipconf.h121
-rw-r--r--src/Common/libzip/zipint.h465
-rw-r--r--src/Common/libzip/zipwin32.h82
113 files changed, 14440 insertions, 0 deletions
diff --git a/src/Common/libzip/LICENSE b/src/Common/libzip/LICENSE
new file mode 100644
index 00000000..8e3a62c7
--- /dev/null
+++ b/src/Common/libzip/LICENSE
@@ -0,0 +1,31 @@
+Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
+
+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.
diff --git a/src/Common/libzip/NEWS.md b/src/Common/libzip/NEWS.md
new file mode 100644
index 00000000..c915ce62
--- /dev/null
+++ b/src/Common/libzip/NEWS.md
@@ -0,0 +1,159 @@
+1.1.3 [2016-05-28]
+==================
+
+* Fix build on Windows when using autoconf.
+
+1.1.2 [2016-02-19]
+==================
+
+* Improve support for 3MF files
+
+1.1.1 [2016-02-07]
+==================
+
+* Build fixes for Linux
+* Fix some warnings reported by PVS-Studio
+
+1.1 [2016-01-26]
+================
+
+* ziptool(1): command line tool to modify zip archives
+* Speedups for archives with many entries
+* Coverity fixes
+* Better APK support
+* Support for running tests on Windows
+* More build fixes for Windows
+* Portability fixes
+* Documentation improvements
+
+1.0.1 [2015-05-04]
+==================
+
+* Build fixes for Windows.
+
+1.0 [2015-05-03]
+================
+
+* 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.
+
+0.11.2 [2013-12-19]
+===================
+
+* 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.
+
+0.11.1 [2013-04-27]
+===================
+
+* Fix bugs in zip_set_file_compression().
+* Include Xcode build infrastructure.
+
+0.11 [2013-03-23]
+=================
+
+* Added Zip64 support (large file support)
+* Added UTF-8 support for file names, file comments, and archive comments
+* Changed API for name and comment related functions for UTF-8 support
+* Added zip_discard()
+* Added ZIP_TRUNCATE for zip_open()
+* Added zip_set_file_compression()
+* Added API for accessing and modifying extra fields
+* Improved API type consistency
+* Use gcc4's visibility __attribute__
+* More changes for Windows support
+* Additional test cases
+
+0.10.1 [2012-03-20]
+===================
+
+* Fixed CVE-2012-1162
+* Fixed CVE-2012-1163
+
+0.10 [2010-03-18]
+=================
+
+* 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
+* Fix memory leak in error case in zip_open()
+* Fixed CVE-2011-0421 (no security implications though)
+* More documentation.
+
+0.9.3 [2010-02-01]
+==================
+
+* Include m4/ directory in distribution; some packagers need it.
+
+0.9.2 [2010-01-31]
+==================
+
+* Avoid passing uninitialized data to deflate().
+* Fix memory leak when closing zip archives.
+
+0.9.1 [2010-01-24]
+==================
+
+* 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.
+
+0.9 [2008-07-25]
+==================
+
+* on Windows, explictly set dllimport/dllexport
+* remove erroneous references to GPL
+* add support for torrentzip
+* new functions: zip_get_archive_flag, zip_set_archive_flag
+* zip_source_zip: add flag to force recompression
+* zip_sorce_file: only keep file open while reading from it
+
+0.8 [2007-06-06]
+==================
+
+* fix for zip archives larger than 2GiB
+* fix zip_error_strerror to include libzip error string
+* add support for reading streamed zip files
+* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
+* add basic support for building with CMake (incomplete)
+
+0.7.1 [2006-05-18]
+==================
+
+* bugfix for zip_close
+
+0.7 [2006-05-06]
+================
+
+* struct zip_stat increased for future encryption support
+* zip_add return value changed (now returns new index of added file)
+* shared library major bump because of previous two
+* added functions for reading and writing file and archive comments.
+ New functions: zip_get_archive_comment, zip_get_file_comment,
+ zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
+
+0.6.1 [2005-07-14]
+==================
+
+* various bug fixes
+
+0.6 [2005-06-09]
+================
+
+* first standalone release
+* changed license to three-clause BSD
+* overhauled API
+* added man pages
+* install zipcmp and zipmerge
diff --git a/src/Common/libzip/compat.h b/src/Common/libzip/compat.h
new file mode 100644
index 00000000..4cc6703f
--- /dev/null
+++ b/src/Common/libzip/compat.h
@@ -0,0 +1,181 @@
+#ifndef _HAD_LIBZIP_COMPAT_H
+#define _HAD_LIBZIP_COMPAT_H
+
+/*
+ compat.h -- compatibility defines.
+ 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* to have *_MAX definitions for all types when compiling with g++ */
+#define __STDC_LIMIT_MACROS
+
+#ifdef _WIN32
+#define ZIP_EXTERN __declspec(dllexport)
+/* for dup(), close(), etc. */
+#include <io.h>
+#endif
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+typedef char bool;
+#define true 1
+#define false 0
+#endif
+
+#include <errno.h>
+
+/* at least MinGW does not provide EOPNOTSUPP, see
+ * http://sourceforge.net/p/mingw/bugs/263/
+ */
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP EINVAL
+#endif
+
+/* at least MinGW does not provide EOVERFLOW, see
+ * http://sourceforge.net/p/mingw/bugs/242/
+ */
+#ifndef EOVERFLOW
+#define EOVERFLOW EFBIG
+#endif
+
+#ifdef _WIN32
+#if defined(HAVE__CLOSE)
+#define close _close
+#endif
+#if defined(HAVE__DUP)
+#define dup _dup
+#endif
+/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
+#if defined(HAVE__FDOPEN)
+#define fdopen _fdopen
+#endif
+#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
+#define fileno _fileno
+#endif
+/* Windows' open() doesn't understand Unix permissions */
+#if defined(HAVE__OPEN)
+#define open(a, b, c) _open((a), (b))
+#endif
+#if defined(HAVE__SNPRINTF)
+#define snprintf _snprintf
+#endif
+#if defined(HAVE__STRDUP)
+#if !defined(HAVE_STRDUP) || defined(_WIN32)
+#undef strdup
+#define strdup _strdup
+#endif
+#endif
+#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
+#define _setmode setmode
+#endif
+#endif
+
+#ifndef HAVE_FSEEKO
+#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
+#endif
+
+#ifndef HAVE_FTELLO
+#define ftello(s) ((long)ftell((s)))
+#endif
+
+#ifndef HAVE_MKSTEMP
+int _zip_mkstemp(char *);
+#define mkstemp _zip_mkstemp
+#endif
+
+#if !defined(HAVE_STRCASECMP)
+#if defined(HAVE__STRICMP)
+#define strcasecmp _stricmp
+#elif defined(HAVE_STRICMP)
+#define strcasecmp stricmp
+#endif
+#endif
+
+#if SIZEOF_OFF_T == 8
+#define ZIP_OFF_MAX ZIP_INT64_MAX
+#define ZIP_OFF_MIN ZIP_INT64_MIN
+#elif SIZEOF_OFF_T == 4
+#define ZIP_OFF_MAX ZIP_INT32_MAX
+#define ZIP_OFF_MIN ZIP_INT32_MIN
+#elif SIZEOF_OFF_T == 2
+#define ZIP_OFF_MAX ZIP_INT16_MAX
+#define ZIP_OFF_MIN ZIP_INT16_MIN
+#else
+#error unsupported size of off_t
+#endif
+
+#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
+#define ZIP_FSEEK_MAX ZIP_OFF_MAX
+#define ZIP_FSEEK_MIN ZIP_OFF_MIN
+#else
+#include <limits.h>
+#define ZIP_FSEEK_MAX LONG_MAX
+#define ZIP_FSEEK_MIN LONG_MIN
+#endif
+
+#ifndef SIZE_MAX
+#if SIZEOF_SIZE_T == 8
+#define SIZE_MAX ZIP_INT64_MAX
+#elif SIZEOF_SIZE_T == 4
+#define SIZE_MAX ZIP_INT32_MAX
+#elif SIZEOF_SIZE_T == 2
+#define SIZE_MAX ZIP_INT16_MAX
+#else
+#error unsupported size of size_t
+#endif
+#endif
+
+#ifndef PRId64
+#ifdef _MSC_VER
+#define PRId64 "I64d"
+#else
+#define PRId64 "lld"
+#endif
+#endif
+
+#ifndef PRIu64
+#ifdef _MSC_VER
+#define PRIu64 "I64u"
+#else
+#define PRIu64 "llu"
+#endif
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+
+#endif /* compat.h */
diff --git a/src/Common/libzip/config.h b/src/Common/libzip/config.h
new file mode 100644
index 00000000..f4dec478
--- /dev/null
+++ b/src/Common/libzip/config.h
@@ -0,0 +1,72 @@
+#ifndef HAD_CONFIG_H
+#define HAD_CONFIG_H
+#ifndef _HAD_ZIPCONF_H
+#include "zipconf.h"
+#endif
+/* BEGIN DEFINES */
+/* #undef HAVE___PROGNAME */
+#define HAVE__CLOSE
+#define HAVE__DUP
+#define HAVE__FDOPEN
+#define HAVE__FILENO
+#define HAVE__OPEN
+#define HAVE__SETMODE
+#define HAVE__SNPRINTF
+#define HAVE__STRDUP
+#define HAVE__STRICMP
+#define HAVE_FILENO
+/* #undef HAVE_FSEEKO */
+/* #undef HAVE_FTELLO */
+/* #undef HAVE_GETPROGNAME */
+#define HAVE_OPEN
+/* #undef HAVE_MKSTEMP */
+#define HAVE_SETMODE
+/* #undef HAVE_SNPRINTF */
+/* #undef HAVE_SSIZE_T_LIBZIP */
+/* #undef HAVE_STRCASECMP */
+#define HAVE_STRDUP
+#define HAVE_STRICMP
+/* #undef HAVE_STRUCT_TM_TM_ZONE */
+/* #undef HAVE_STDBOOL_H */
+/* #undef HAVE_STRINGS_H */
+/* #undef HAVE_UNISTD_H */
+#define __INT8_LIBZIP 1
+#define INT8_T_LIBZIP 1
+#define UINT8_T_LIBZIP 1
+#define __INT16_LIBZIP 2
+#define INT16_T_LIBZIP 2
+#define UINT16_T_LIBZIP 2
+#define __INT32_LIBZIP 4
+#define INT32_T_LIBZIP 4
+#define UINT32_T_LIBZIP 4
+#define __INT64_LIBZIP 8
+#define INT64_T_LIBZIP 8
+#define UINT64_T_LIBZIP 8
+#define SIZEOF_OFF_T 4
+#ifdef _WIN64
+#define SIZE_T_LIBZIP 8
+#else
+#define SIZE_T_LIBZIP 4
+#endif
+/* #undef SSIZE_T_LIBZIP */
+/* #undef HAVE_DIRENT_H */
+/* #undef HAVE_NDIR_H */
+/* #undef HAVE_SYS_DIR_H */
+/* #undef HAVE_SYS_NDIR_H */
+/* END DEFINES */
+#define PACKAGE "libzip"
+#define VERSION "1.1.3"
+
+#ifndef HAVE_SSIZE_T_LIBZIP
+# if SIZE_T_LIBZIP == INT_LIBZIP
+typedef int ssize_t;
+# elif SIZE_T_LIBZIP == LONG_LIBZIP
+typedef long ssize_t;
+# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
+typedef long long ssize_t;
+# else
+#error no suitable type for ssize_t found
+# endif
+#endif
+
+#endif /* HAD_CONFIG_H */
diff --git a/src/Common/libzip/mkstemp.c b/src/Common/libzip/mkstemp.c
new file mode 100644
index 00000000..2ccd3a48
--- /dev/null
+++ b/src/Common/libzip/mkstemp.c
@@ -0,0 +1,150 @@
+/* Adapted from NetBSB libc by Dieter Baron */
+
+/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+
+int
+_zip_mkstemp(char *path)
+{
+#ifdef _WIN32
+ 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;
+ }
+
+ /* 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;
+ }
+ }
+
+ 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;
+ }
+ }
+ }
+ /*NOTREACHED*/
+#endif
+}
diff --git a/src/Common/libzip/zip.h b/src/Common/libzip/zip.h
new file mode 100644
index 00000000..27141b34
--- /dev/null
+++ b/src/Common/libzip/zip.h
@@ -0,0 +1,422 @@
+#ifndef _HAD_ZIP_H
+#define _HAD_ZIP_H
+
+/*
+ zip.h -- exported declarations.
+ 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>
+
+ 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.
+*/
+
+
+#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
+extern "C" {
+#if 0
+} /* fix autoindent */
+#endif
+#endif
+
+#include <zipconf.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <time.h>
+
+/* flags for zip_open */
+
+#define ZIP_CREATE 1
+#define ZIP_EXCL 2
+#define ZIP_CHECKCONS 4
+#define ZIP_TRUNCATE 8
+#define ZIP_RDONLY 16
+
+
+/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
+
+#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 */
+
+/* archive global flags flags */
+
+#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
+
+
+/* create a new extra field */
+
+#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
+#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX
+
+
+/* libzip error codes */
+
+#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 */
+
+/* type of system error value */
+
+#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 */
+
+/* compression methods */
+
+#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 */
+/* 11 - Reserved by PKWARE */
+#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */
+/* 13 - Reserved by PKWARE */
+#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_WAVPACK 97 /* WavPack compressed data */
+#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
+
+/* encryption methods */
+
+#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_AES_128 0x660e
+#define ZIP_EM_AES_192 0x660f
+#define ZIP_EM_AES_256 0x6610
+#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
+#define ZIP_EM_RC4 0x6801
+#endif
+#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
+
+
+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 */
+};
+typedef enum zip_source_cmd zip_source_cmd_t;
+
+#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (1<<(cmd))
+
+#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE))
+
+#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS))
+
+#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
+ | ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
+
+/* for use by sources */
+struct zip_source_args_seek {
+ zip_int64_t offset;
+ int whence;
+};
+
+typedef struct zip_source_args_seek zip_source_args_seek_t;
+#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data))
+
+
+/* error information */
+/* use zip_error_*() to access */
+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 */
+};
+
+#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 */
+};
+
+struct zip;
+struct zip_file;
+struct zip_source;
+
+typedef struct zip zip_t;
+typedef struct zip_error zip_error_t;
+typedef struct zip_file zip_file_t;
+typedef struct zip_source zip_source_t;
+typedef struct zip_stat zip_stat_t;
+
+typedef zip_uint32_t zip_flags_t;
+
+typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
+
+
+#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 */
+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 */
+#endif
+
+ZIP_EXTERN int zip_archive_set_tempdir(zip_t *, const char *);
+ZIP_EXTERN int zip_close(zip_t *);
+ZIP_EXTERN int zip_delete(zip_t *, zip_uint64_t);
+ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *, const char *, zip_flags_t);
+ZIP_EXTERN void zip_discard(zip_t *);
+
+ZIP_EXTERN zip_error_t *zip_get_error(zip_t *);
+ZIP_EXTERN void zip_error_clear(zip_t *);
+ZIP_EXTERN int zip_error_code_zip(const zip_error_t *);
+ZIP_EXTERN int zip_error_code_system(const zip_error_t *);
+ZIP_EXTERN void zip_error_fini(zip_error_t *);
+ZIP_EXTERN void zip_error_init(zip_error_t *);
+ZIP_EXTERN void zip_error_init_with_code(zip_error_t *, int);
+ZIP_EXTERN void zip_error_set(zip_error_t *, int, int);
+ZIP_EXTERN const char *zip_error_strerror(zip_error_t *);
+ZIP_EXTERN int zip_error_system_type(const zip_error_t *);
+ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *, void *, zip_uint64_t);
+
+ZIP_EXTERN int zip_fclose(zip_file_t *);
+ZIP_EXTERN zip_t *zip_fdopen(int, int, int *);
+ZIP_EXTERN zip_int64_t zip_file_add(zip_t *, const char *, zip_source_t *, zip_flags_t);
+ZIP_EXTERN void zip_file_error_clear(zip_file_t *);
+ZIP_EXTERN int zip_file_extra_field_delete(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_set(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
+ZIP_EXTERN const char *zip_file_get_comment(zip_t *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
+ZIP_EXTERN zip_error_t *zip_file_get_error(zip_file_t *);
+ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t *, zip_uint32_t *);
+ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t);
+ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t);
+ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
+ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
+ZIP_EXTERN const char *zip_file_strerror(zip_file_t *);
+ZIP_EXTERN zip_file_t *zip_fopen(zip_t *, const char *, zip_flags_t);
+ZIP_EXTERN zip_file_t *zip_fopen_encrypted(zip_t *, const char *, zip_flags_t, const char *);
+ZIP_EXTERN zip_file_t *zip_fopen_index(zip_t *, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_file_t *zip_fopen_index_encrypted(zip_t *, zip_uint64_t, zip_flags_t, const char *);
+ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *, void *, zip_uint64_t);
+ZIP_EXTERN const char *zip_get_archive_comment(zip_t *, int *, zip_flags_t);
+ZIP_EXTERN int zip_get_archive_flag(zip_t *, zip_flags_t, zip_flags_t);
+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 zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
+ZIP_EXTERN zip_t *zip_open(const char *, int, int *);
+ZIP_EXTERN zip_t *zip_open_from_source(zip_source_t *, int, zip_error_t *);
+ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
+ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
+ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
+ZIP_EXTERN int zip_set_file_compression(zip_t *, zip_uint64_t, zip_int32_t, zip_uint32_t);
+ZIP_EXTERN int zip_source_begin_write(zip_source_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 int zip_source_close(zip_source_t *);
+ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
+ZIP_EXTERN zip_error_t *zip_source_error(zip_source_t *src);
+ZIP_EXTERN zip_source_t *zip_source_file(zip_t *, const char *, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *zip_source_file_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
+ZIP_EXTERN zip_source_t *zip_source_filep(zip_t *, FILE *, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *zip_source_filep_create(FILE *, zip_uint64_t, zip_int64_t, zip_error_t *);
+ZIP_EXTERN void zip_source_free(zip_source_t *);
+ZIP_EXTERN zip_source_t *zip_source_function(zip_t *, zip_source_callback, void *);
+ZIP_EXTERN zip_source_t *zip_source_function_create(zip_source_callback, void *, zip_error_t *);
+ZIP_EXTERN int zip_source_is_deleted(zip_source_t *);
+ZIP_EXTERN void zip_source_keep(zip_source_t *);
+ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
+ZIP_EXTERN int zip_source_open(zip_source_t *);
+ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t);
+ZIP_EXTERN void zip_source_rollback_write(zip_source_t *);
+ZIP_EXTERN int zip_source_seek(zip_source_t *, zip_int64_t, int);
+ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *);
+ZIP_EXTERN int zip_source_seek_write(zip_source_t *, zip_int64_t, int);
+ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *);
+ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *);
+ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *);
+#ifdef _WIN32
+ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
+ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *);
+ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
+#endif
+ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
+ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
+ZIP_EXTERN int zip_stat(zip_t *, const char *, zip_flags_t, zip_stat_t *);
+ZIP_EXTERN int zip_stat_index(zip_t *, zip_uint64_t, zip_flags_t, zip_stat_t *);
+ZIP_EXTERN void zip_stat_init(zip_stat_t *);
+ZIP_EXTERN const char *zip_strerror(zip_t *);
+ZIP_EXTERN int zip_unchange(zip_t *, zip_uint64_t);
+ZIP_EXTERN int zip_unchange_all(zip_t *);
+ZIP_EXTERN int zip_unchange_archive(zip_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAD_ZIP_H */
diff --git a/src/Common/libzip/zip_add.c b/src/Common/libzip/zip_add.c
new file mode 100644
index 00000000..d1be133b
--- /dev/null
+++ b/src/Common/libzip/zip_add.c
@@ -0,0 +1,50 @@
+/*
+ zip_add.c -- add file via callback function
+ Copyright (C) 1999-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+/*
+ 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.
+*/
+
+ZIP_EXTERN zip_int64_t
+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
new file mode 100644
index 00000000..14bdeda1
--- /dev/null
+++ b/src/Common/libzip/zip_add_dir.c
@@ -0,0 +1,45 @@
+/*
+ zip_add_dir.c -- add directory
+ Copyright (C) 1999-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+ZIP_EXTERN zip_int64_t
+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
new file mode 100644
index 00000000..9a9465c5
--- /dev/null
+++ b/src/Common/libzip/zip_add_entry.c
@@ -0,0 +1,81 @@
+/*
+ zip_add_entry.c -- create and init struct zip_entry
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+zip_int64_t
+_zip_add_entry(zip_t *za)
+{
+ zip_uint64_t idx;
+
+ if (za->nentry+1 >= za->nentry_alloc) {
+ zip_entry_t *rentries;
+ zip_uint64_t nalloc = za->nentry_alloc;
+ zip_uint64_t additional_entries = 2 * nalloc;
+ zip_uint64_t realloc_size;
+
+ if (additional_entries < 16) {
+ additional_entries = 16;
+ }
+ else if (additional_entries > 1024) {
+ additional_entries = 1024;
+ }
+ /* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */
+ nalloc += additional_entries;
+ realloc_size = sizeof(struct zip_entry) * (size_t)nalloc;
+
+ if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
+ if (!rentries) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ za->entry = rentries;
+ za->nentry_alloc = nalloc;
+ }
+
+ idx = za->nentry++;
+
+ _zip_entry_init(za->entry+idx);
+
+ return (zip_int64_t)idx;
+}
diff --git a/src/Common/libzip/zip_buffer.c b/src/Common/libzip/zip_buffer.c
new file mode 100644
index 00000000..43864f9b
--- /dev/null
+++ b/src/Common/libzip/zip_buffer.c
@@ -0,0 +1,321 @@
+/*
+ zip_buffer.c -- bounds checked access to memory buffer
+ 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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+zip_uint8_t *
+_zip_buffer_data(zip_buffer_t *buffer)
+{
+ return buffer->data;
+}
+
+
+void
+_zip_buffer_free(zip_buffer_t *buffer)
+{
+ if (buffer == NULL) {
+ return;
+ }
+
+ if (buffer->free_data) {
+ free(buffer->data);
+ }
+
+ free(buffer);
+}
+
+
+bool
+_zip_buffer_eof(zip_buffer_t *buffer)
+{
+ return buffer->ok && buffer->offset == buffer->size;
+}
+
+
+zip_uint8_t *
+_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length)
+{
+ zip_uint8_t *data;
+
+ if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
+ buffer->ok = false;
+ return NULL;
+ }
+
+ data = buffer->data + buffer->offset;
+ buffer->offset += length;
+ return data;
+}
+
+
+zip_uint16_t
+_zip_buffer_get_16(zip_buffer_t *buffer)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 2);
+
+ if (data == NULL) {
+ return 0;
+ }
+
+ return (zip_uint16_t)(data[0] + (data[1] << 8));
+}
+
+
+zip_uint32_t
+_zip_buffer_get_32(zip_buffer_t *buffer)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 4);
+
+ if (data == NULL) {
+ return 0;
+ }
+
+ return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
+}
+
+
+zip_uint64_t
+_zip_buffer_get_64(zip_buffer_t *buffer)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 8);
+
+ if (data == NULL) {
+ return 0;
+ }
+
+ return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0];
+}
+
+
+
+zip_uint8_t
+_zip_buffer_get_8(zip_buffer_t *buffer)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 1);
+
+ if (data == NULL) {
+ return 0;
+ }
+
+ return data[0];
+}
+
+
+zip_uint64_t
+_zip_buffer_left(zip_buffer_t *buffer)
+{
+ return buffer->ok ? buffer->size - buffer->offset : 0;
+}
+
+
+zip_buffer_t *
+_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
+{
+ bool free_data = (data == NULL);
+ zip_buffer_t *buffer;
+
+ if (data == NULL) {
+ if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
+ return NULL;
+ }
+ }
+
+ if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) {
+ if (free_data) {
+ free(data);
+ }
+ return NULL;
+ }
+
+ buffer->ok = true;
+ buffer->data = data;
+ buffer->size = size;
+ buffer->offset = 0;
+ buffer->free_data = free_data;
+
+ return buffer;
+}
+
+
+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_t *buffer;
+
+ if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if (_zip_read(src, buffer->data, size, error) < 0) {
+ _zip_buffer_free(buffer);
+ return NULL;
+ }
+
+ return buffer;
+}
+
+
+zip_uint64_t
+_zip_buffer_offset(zip_buffer_t *buffer)
+{
+ return buffer->ok ? buffer->offset : 0;
+}
+
+
+bool
+_zip_buffer_ok(zip_buffer_t *buffer)
+{
+ return buffer->ok;
+}
+
+
+int
+_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length)
+{
+ zip_uint8_t *dst = _zip_buffer_get(buffer, length);
+
+ if (dst == NULL) {
+ return -1;
+ }
+
+ memcpy(dst, src, length);
+ return 0;
+}
+
+
+int
+_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 2);
+
+ if (data == NULL) {
+ return -1;
+ }
+
+ data[0] = (zip_uint8_t)(i & 0xff);
+ data[1] = (zip_uint8_t)((i >> 8) & 0xff);
+
+ return 0;
+}
+
+
+int
+_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 4);
+
+ if (data == NULL) {
+ return -1;
+ }
+
+ data[0] = (zip_uint8_t)(i & 0xff);
+ data[1] = (zip_uint8_t)((i >> 8) & 0xff);
+ data[2] = (zip_uint8_t)((i >> 16) & 0xff);
+ data[3] = (zip_uint8_t)((i >> 24) & 0xff);
+
+ return 0;
+}
+
+
+int
+_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 8);
+
+ if (data == NULL) {
+ return -1;
+ }
+
+ data[0] = (zip_uint8_t)(i & 0xff);
+ data[1] = (zip_uint8_t)((i >> 8) & 0xff);
+ data[2] = (zip_uint8_t)((i >> 16) & 0xff);
+ data[3] = (zip_uint8_t)((i >> 24) & 0xff);
+ data[4] = (zip_uint8_t)((i >> 32) & 0xff);
+ data[5] = (zip_uint8_t)((i >> 40) & 0xff);
+ data[6] = (zip_uint8_t)((i >> 48) & 0xff);
+ data[7] = (zip_uint8_t)((i >> 56) & 0xff);
+
+ return 0;
+}
+
+
+int
+_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i)
+{
+ zip_uint8_t *data = _zip_buffer_get(buffer, 1);
+
+ if (data == NULL) {
+ return -1;
+ }
+
+ data[0] = i;
+
+ return 0;
+}
+
+
+int
+_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
+{
+ if (offset > buffer->size) {
+ buffer->ok = false;
+ return -1;
+ }
+
+ buffer->ok = true;
+ buffer->offset = offset;
+
+ return 0;
+}
+
+
+int
+_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
+ zip_uint64_t offset = buffer->offset + length;
+
+ if (offset < buffer->offset) {
+ buffer->ok = false;
+ return -1;
+ }
+ return _zip_buffer_set_offset(buffer, offset);
+}
+
+zip_uint64_t
+_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
new file mode 100644
index 00000000..b5eca67a
--- /dev/null
+++ b/src/Common/libzip/zip_close.c
@@ -0,0 +1,492 @@
+/*
+ zip_close.c -- close zip archive and update changes
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+
+/* 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 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_int64_t off;
+ int error;
+ zip_filelist_t *filelist;
+ int changed;
+
+ if (za == NULL)
+ return -1;
+
+ changed = _zip_changed(za, &survivors);
+
+ /* don't create zip files with no entries */
+ if (survivors == 0) {
+ if ((za->open_flags & ZIP_TRUNCATE) || changed) {
+ if (zip_source_remove(za->src) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+ }
+ zip_discard(za);
+ return 0;
+ }
+
+ if (!changed) {
+ zip_discard(za);
+ return 0;
+ }
+
+ if (survivors > za->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+
+ if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL)
+ return -1;
+
+ /* create list of files with index into original archive */
+ for (i=j=0; i<za->nentry; i++) {
+ if (za->entry[i].deleted)
+ continue;
+
+ if (j >= survivors) {
+ free(filelist);
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+
+ filelist[j].idx = i;
+ j++;
+ }
+ 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);
+ return -1;
+ }
+
+ error = 0;
+ for (j=0; j<survivors; j++) {
+ int new_data;
+ zip_entry_t *entry;
+ zip_dirent_t *de;
+
+ i = filelist[j].idx;
+ entry = za->entry+i;
+
+ new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
+
+ /* create new local directory entry */
+ 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;
+ }
+ }
+ de = entry->changes;
+
+ if (_zip_read_local_ef(za, i) < 0) {
+ error = 1;
+ break;
+ }
+
+ if ((off = zip_source_tell_write(za->src)) < 0) {
+ error = 1;
+ break;
+ }
+ de->offset = (zip_uint64_t)off;
+
+ if (new_data) {
+ zip_source_t *zs;
+
+ zs = NULL;
+ if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
+ if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
+ error = 1;
+ break;
+ }
+ }
+
+ /* add_data writes dirent */
+ if (add_data(za, zs ? zs : entry->source, de) < 0) {
+ error = 1;
+ if (zs)
+ zip_source_free(zs);
+ break;
+ }
+ if (zs)
+ zip_source_free(zs);
+ }
+ else {
+ zip_uint64_t offset;
+
+ /* when copying data, all sizes are known -> no data descriptor needed */
+ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
+ if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
+ error = 1;
+ break;
+ }
+ if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
+ error = 1;
+ break;
+ }
+ if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ error = 1;
+ break;
+ }
+ if (copy_data(za, de->comp_size) < 0) {
+ error = 1;
+ break;
+ }
+ }
+ }
+
+ if (!error) {
+ if (write_cdir(za, filelist, survivors) < 0)
+ error = 1;
+ }
+
+ free(filelist);
+
+ if (!error) {
+ if (zip_source_commit_write(za->src) != 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ error = 1;
+ }
+ }
+
+ if (error) {
+ zip_source_rollback_write(za->src);
+ return -1;
+ }
+
+ zip_discard(za);
+
+ return 0;
+}
+
+
+static int
+add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
+{
+ zip_int64_t offstart, offdata, offend;
+ struct zip_stat st;
+ zip_source_t *s2;
+ int ret;
+ int is_zip64;
+ zip_flags_t flags;
+
+ if (zip_source_stat(src, &st) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ return -1;
+ }
+
+ if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
+ st.valid |= ZIP_STAT_COMP_METHOD;
+ st.comp_method = ZIP_CM_STORE;
+ }
+
+ if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
+ de->comp_method = st.comp_method;
+ else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
+ st.valid |= ZIP_STAT_COMP_SIZE;
+ st.comp_size = st.size;
+ }
+ else {
+ /* we'll recompress */
+ st.valid &= ~ZIP_STAT_COMP_SIZE;
+ }
+
+
+ flags = ZIP_EF_LOCAL;
+
+ if ((st.valid & ZIP_STAT_SIZE) == 0)
+ flags |= ZIP_FL_FORCE_ZIP64;
+ else {
+ de->uncomp_size = 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))))
+ flags |= ZIP_FL_FORCE_ZIP64;
+ }
+ else
+ de->comp_size = st.comp_size;
+ }
+
+ if ((offstart = zip_source_tell_write(za->src)) < 0) {
+ return -1;
+ }
+
+ /* as long as we don't support non-seekable output, clear data descriptor bit */
+ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
+ if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0)
+ return -1;
+
+
+ if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) {
+ zip_source_t *s_store, *s_crc;
+ zip_compression_implementation comp_impl;
+
+ if (st.comp_method != ZIP_CM_STORE) {
+ if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ return -1;
+ }
+ if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
+ /* error set by comp_impl */
+ return -1;
+ }
+ }
+ else {
+ /* to have the same reference count to src as in the case where it's not stored */
+ zip_source_keep(src);
+ s_store = src;
+ }
+
+ s_crc = zip_source_crc(za, s_store, 0);
+ zip_source_free(s_store);
+ if (s_crc == NULL) {
+ return -1;
+ }
+
+ if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
+ if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ zip_source_free(s_crc);
+ return -1;
+ }
+ s2 = comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE);
+ zip_source_free(s_crc);
+ if (s2 == NULL) {
+ return -1;
+ }
+ }
+ else {
+ s2 = s_crc;
+ }
+ }
+ else {
+ zip_source_keep(src);
+ s2 = src;
+ }
+
+ if ((offdata = zip_source_tell_write(za->src)) < 0) {
+ return -1;
+ }
+
+ ret = copy_source(za, s2);
+
+ if (zip_source_stat(s2, &st) < 0)
+ ret = -1;
+
+ zip_source_free(s2);
+
+ if (ret < 0)
+ return -1;
+
+ if ((offend = zip_source_tell_write(za->src)) < 0) {
+ return -1;
+ }
+
+ if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+
+ 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);
+ return -1;
+ }
+
+ if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
+ if (st.valid & ZIP_STAT_MTIME)
+ de->last_mod = st.mtime;
+ else
+ time(&de->last_mod);
+ }
+ de->comp_method = st.comp_method;
+ de->crc = st.crc;
+ de->uncomp_size = st.size;
+ de->comp_size = (zip_uint64_t)(offend - offdata);
+
+ if ((ret=_zip_dirent_write(za, de, flags)) < 0)
+ return -1;
+
+ if (is_zip64 != ret) {
+ /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+
+
+ if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+copy_data(zip_t *za, zip_uint64_t len)
+{
+ zip_uint8_t buf[BUFSIZE];
+ size_t n;
+
+ while (len > 0) {
+ n = len > sizeof(buf) ? sizeof(buf) : len;
+ if (_zip_read(za->src, buf, n, &za->error) < 0) {
+ return -1;
+ }
+
+ if (_zip_write(za, buf, n) < 0) {
+ return -1;
+ }
+
+ len -= n;
+ }
+
+ return 0;
+}
+
+
+static int
+copy_source(zip_t *za, zip_source_t *src)
+{
+ zip_uint8_t buf[BUFSIZE];
+ zip_int64_t n;
+ int ret;
+
+ if (zip_source_open(src) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ return -1;
+ }
+
+ ret = 0;
+ while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
+ if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
+ ret = -1;
+ break;
+ }
+ }
+
+ if (n < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ ret = -1;
+ }
+
+ zip_source_close(src);
+
+ return ret;
+}
+
+
+static int
+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;
+ }
+
+ if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) {
+ return -1;
+ }
+
+ if ((end = zip_source_tell_write(za->src)) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+_zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
+{
+ int changed;
+ zip_uint64_t i, survivors;
+
+ changed = 0;
+ survivors = 0;
+
+ 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))
+ changed = 1;
+ if (!za->entry[i].deleted)
+ survivors++;
+ }
+
+ if (survivorsp)
+ *survivorsp = survivors;
+
+ return changed;
+}
diff --git a/src/Common/libzip/zip_delete.c b/src/Common/libzip/zip_delete.c
new file mode 100644
index 00000000..34520b03
--- /dev/null
+++ b/src/Common/libzip/zip_delete.c
@@ -0,0 +1,70 @@
+/*
+ zip_delete.c -- delete file from zip archive
+ 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>
+
+ 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"
+
+
+ZIP_EXTERN int
+zip_delete(zip_t *za, zip_uint64_t idx)
+{
+ const char *name;
+
+ if (idx >= za->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if ((name=_zip_get_name(za, idx, 0, &za->error)) == NULL) {
+ return -1;
+ }
+
+ if (!_zip_hash_delete(za->names, (const zip_uint8_t *)name, &za->error)) {
+ return -1;
+ }
+
+ /* allow duplicate file names, because the file will
+ * be removed directly afterwards */
+ if (_zip_unchange(za, idx, 1) != 0)
+ return -1;
+
+ za->entry[idx].deleted = 1;
+
+ return 0;
+}
+
diff --git a/src/Common/libzip/zip_dir_add.c b/src/Common/libzip/zip_dir_add.c
new file mode 100644
index 00000000..f535b21f
--- /dev/null
+++ b/src/Common/libzip/zip_dir_add.c
@@ -0,0 +1,93 @@
+/*
+ zip_dir_add.c -- add directory
+ Copyright (C) 1999-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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+ZIP_EXTERN zip_int64_t
+zip_dir_add(zip_t *za, const char *name, zip_flags_t flags)
+{
+ size_t len;
+ zip_int64_t idx;
+ char *s;
+ zip_source_t *source;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (name == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ s = NULL;
+ len = strlen(name);
+
+ if (name[len-1] != '/') {
+ if ((s=(char *)malloc(len+2)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ strcpy(s, name);
+ s[len] = '/';
+ s[len+1] = '\0';
+ }
+
+ if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
+ free(s);
+ return -1;
+ }
+
+ idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
+
+ free(s);
+
+ if (idx < 0)
+ zip_source_free(source);
+ else {
+ if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) {
+ zip_delete(za, (zip_uint64_t)idx);
+ return -1;
+ }
+ }
+
+ return idx;
+}
diff --git a/src/Common/libzip/zip_dirent.c b/src/Common/libzip/zip_dirent.c
new file mode 100644
index 00000000..74f89880
--- /dev/null
+++ b/src/Common/libzip/zip_dirent.c
@@ -0,0 +1,913 @@
+/*
+ zip_dirent.c -- read directory entry (local or central), clean dirent
+ 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.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "zipint.h"
+
+static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
+static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
+static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
+
+
+void
+_zip_cdir_free(zip_cdir_t *cd)
+{
+ zip_uint64_t i;
+
+ if (!cd)
+ return;
+
+ for (i=0; i<cd->nentry; i++)
+ _zip_entry_finalize(cd->entry+i);
+ free(cd->entry);
+ _zip_string_free(cd->comment);
+ free(cd);
+}
+
+
+zip_cdir_t *
+_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
+{
+ zip_cdir_t *cd;
+ zip_uint64_t i;
+
+ if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if (nentry == 0)
+ cd->entry = NULL;
+ else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(cd);
+ return NULL;
+ }
+
+ for (i=0; i<nentry; i++)
+ _zip_entry_init(cd->entry+i);
+
+ cd->nentry = cd->nentry_alloc = nentry;
+ cd->size = cd->offset = 0;
+ cd->comment = NULL;
+
+ return cd;
+}
+
+
+zip_int64_t
+_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
+{
+ zip_uint64_t offset, size;
+ zip_string_t *comment;
+ zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
+ zip_buffer_t *buffer;
+ zip_int64_t off;
+ zip_uint64_t i;
+ bool is_zip64;
+ int ret;
+
+ if ((off = zip_source_tell_write(za->src)) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+ offset = (zip_uint64_t)off;
+
+ is_zip64 = false;
+
+ 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)
+ return -1;
+ if (ret)
+ is_zip64 = true;
+ }
+
+ if ((off = zip_source_tell_write(za->src)) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+ size = (zip_uint64_t)off - offset;
+
+ if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
+ is_zip64 = true;
+
+
+ if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ if (is_zip64) {
+ _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
+ _zip_buffer_put_64(buffer, EOCD64LEN-12);
+ _zip_buffer_put_16(buffer, 45);
+ _zip_buffer_put_16(buffer, 45);
+ _zip_buffer_put_32(buffer, 0);
+ _zip_buffer_put_32(buffer, 0);
+ _zip_buffer_put_64(buffer, survivors);
+ _zip_buffer_put_64(buffer, survivors);
+ _zip_buffer_put_64(buffer, size);
+ _zip_buffer_put_64(buffer, offset);
+ _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
+ _zip_buffer_put_32(buffer, 0);
+ _zip_buffer_put_64(buffer, offset+size);
+ _zip_buffer_put_32(buffer, 1);
+ }
+
+ _zip_buffer_put(buffer, EOCD_MAGIC, 4);
+ _zip_buffer_put_32(buffer, 0);
+ _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
+ _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
+ _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
+ _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
+
+ comment = za->comment_changed ? za->comment_changes : za->comment_orig;
+
+ _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+
+ if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+
+ _zip_buffer_free(buffer);
+
+ if (comment) {
+ if (_zip_write(za, comment->raw, comment->length) < 0) {
+ return -1;
+ }
+ }
+
+ return (zip_int64_t)size;
+}
+
+
+zip_dirent_t *
+_zip_dirent_clone(const zip_dirent_t *sde)
+{
+ zip_dirent_t *tde;
+
+ if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
+ return NULL;
+
+ if (sde)
+ memcpy(tde, sde, sizeof(*sde));
+ else
+ _zip_dirent_init(tde);
+
+ tde->changed = 0;
+ tde->cloned = 1;
+
+ return tde;
+}
+
+
+void
+_zip_dirent_finalize(zip_dirent_t *zde)
+{
+ if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
+ _zip_string_free(zde->filename);
+ zde->filename = NULL;
+ }
+ if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
+ _zip_ef_free(zde->extra_fields);
+ zde->extra_fields = NULL;
+ }
+ if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
+ _zip_string_free(zde->comment);
+ zde->comment = NULL;
+ }
+}
+
+
+void
+_zip_dirent_free(zip_dirent_t *zde)
+{
+ if (zde == NULL)
+ return;
+
+ _zip_dirent_finalize(zde);
+ free(zde);
+}
+
+
+void
+_zip_dirent_init(zip_dirent_t *de)
+{
+ de->changed = 0;
+ de->local_extra_fields_read = 0;
+ de->cloned = 0;
+
+ de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
+ de->version_needed = 20; /* 2.0 */
+ de->bitflags = 0;
+ de->comp_method = ZIP_CM_DEFAULT;
+ de->last_mod = 0;
+ de->crc = 0;
+ de->comp_size = 0;
+ de->uncomp_size = 0;
+ de->filename = NULL;
+ de->extra_fields = NULL;
+ de->comment = NULL;
+ de->disk_number = 0;
+ de->int_attrib = 0;
+ de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
+ de->offset = 0;
+}
+
+
+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))
+ return true;
+
+ return false;
+}
+
+
+zip_dirent_t *
+_zip_dirent_new(void)
+{
+ zip_dirent_t *de;
+
+ if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL)
+ return NULL;
+
+ _zip_dirent_init(de);
+ return de;
+}
+
+
+/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
+ Fills the zip directory entry zde.
+
+ If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
+
+ If local is true, it reads a local header instead of a central directory entry.
+
+ Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
+*/
+
+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_uint8_t buf[CDENTRYSIZE];
+ zip_uint16_t dostime, dosdate;
+ zip_uint32_t size, variable_size;
+ zip_uint16_t filename_len, comment_len, ef_len;
+
+ bool from_buffer = (buffer != NULL);
+
+ size = local ? LENTRYSIZE : CDENTRYSIZE;
+
+ if (buffer) {
+ 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 (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+
+ /* convert buffercontents to zip_dirent */
+
+ _zip_dirent_init(zde);
+ if (!local)
+ zde->version_madeby = _zip_buffer_get_16(buffer);
+ else
+ zde->version_madeby = 0;
+ zde->version_needed = _zip_buffer_get_16(buffer);
+ zde->bitflags = _zip_buffer_get_16(buffer);
+ zde->comp_method = _zip_buffer_get_16(buffer);
+
+ /* convert to time_t */
+ dostime = _zip_buffer_get_16(buffer);
+ dosdate = _zip_buffer_get_16(buffer);
+ zde->last_mod = _zip_d2u_time(dostime, dosdate);
+
+ zde->crc = _zip_buffer_get_32(buffer);
+ zde->comp_size = _zip_buffer_get_32(buffer);
+ zde->uncomp_size = _zip_buffer_get_32(buffer);
+
+ filename_len = _zip_buffer_get_16(buffer);
+ ef_len = _zip_buffer_get_16(buffer);
+
+ if (local) {
+ comment_len = 0;
+ zde->disk_number = 0;
+ zde->int_attrib = 0;
+ zde->ext_attrib = 0;
+ zde->offset = 0;
+ } else {
+ comment_len = _zip_buffer_get_16(buffer);
+ zde->disk_number = _zip_buffer_get_16(buffer);
+ zde->int_attrib = _zip_buffer_get_16(buffer);
+ zde->ext_attrib = _zip_buffer_get_32(buffer);
+ zde->offset = _zip_buffer_get_32(buffer);
+ }
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+
+ zde->filename = NULL;
+ zde->extra_fields = NULL;
+ zde->comment = NULL;
+
+ 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;
+ }
+ }
+ else {
+ _zip_buffer_free(buffer);
+
+ if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
+ return -1;
+ }
+ }
+
+ if (filename_len) {
+ 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);
+ }
+ return -1;
+ }
+
+ if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
+ if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ }
+ }
+
+ if (ef_len) {
+ zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
+
+ 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)) {
+ free(ef);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ free(ef);
+ if (local)
+ zde->local_extra_fields_read = 1;
+ }
+
+ if (comment_len) {
+ zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
+ if (!zde->comment) {
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
+ if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ if (!from_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return -1;
+ }
+ }
+ }
+
+ zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
+ zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
+
+ /* Zip64 */
+
+ if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
+ zip_uint16_t got_len;
+ 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);
+ }
+ 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 (zde->uncomp_size == ZIP_UINT32_MAX)
+ zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
+ else if (local) {
+ /* From appnote.txt: This entry in the Local header MUST
+ include BOTH original and compressed file size fields. */
+ (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
+ }
+ if (zde->comp_size == ZIP_UINT32_MAX)
+ zde->comp_size = _zip_buffer_get_64(ef_buffer);
+ if (!local) {
+ if (zde->offset == ZIP_UINT32_MAX)
+ zde->offset = _zip_buffer_get_64(ef_buffer);
+ if (zde->disk_number == ZIP_UINT16_MAX)
+ zde->disk_number = _zip_buffer_get_32(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);
+ }
+
+ if (!_zip_buffer_ok(buffer)) {
+ 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_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
+ if (zde->offset > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_SEEK, EFBIG);
+ return -1;
+ }
+
+ zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
+
+ return (zip_int64_t)(size + variable_size);
+}
+
+
+static zip_string_t *
+_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str)
+{
+ zip_uint16_t ef_len;
+ zip_uint32_t ef_crc;
+ zip_buffer_t *buffer;
+
+ const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
+
+ if (ef == NULL || ef_len < 5 || ef[0] != 1) {
+ return str;
+ }
+
+ if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
+ return str;
+ }
+
+ _zip_buffer_get_8(buffer);
+ ef_crc = _zip_buffer_get_32(buffer);
+
+ 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);
+
+ if (ef_str != NULL) {
+ _zip_string_free(str);
+ str = ef_str;
+ }
+ }
+
+ _zip_buffer_free(buffer);
+
+ return str;
+}
+
+
+zip_int32_t
+_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
+{
+ zip_int32_t size;
+ bool local = (flags & ZIP_EF_LOCAL) != 0;
+ int i;
+ zip_uint8_t b[6];
+ zip_buffer_t *buffer;
+
+ size = local ? LENTRYSIZE : CDENTRYSIZE;
+
+ if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
+ _zip_error_set_from_source(error, src);
+ return -1;
+ }
+
+ if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
+ return -1;
+ }
+
+ for (i=0; i<(local ? 2 : 3); i++) {
+ size += _zip_buffer_get_16(buffer);
+ }
+
+ if (!_zip_buffer_eof(buffer)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+
+ _zip_buffer_free(buffer);
+ return size;
+}
+
+
+/* _zip_dirent_write
+ Writes zip directory entry.
+
+ If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
+ directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
+
+ Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
+ returned.
+*/
+
+int
+_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
+{
+ zip_uint16_t dostime, dosdate;
+ zip_encoding_type_t com_enc, name_enc;
+ zip_extra_field_t *ef;
+ zip_extra_field_t *ef64;
+ zip_uint32_t ef_total_size;
+ bool is_zip64;
+ bool is_really_zip64;
+ zip_uint8_t buf[CDENTRYSIZE];
+ zip_buffer_t *buffer;
+
+ ef = NULL;
+
+ name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
+ com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
+
+ 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;
+ else {
+ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
+ if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
+ ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
+ if (ef == NULL)
+ return -1;
+ }
+ 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);
+ if (ef2 == NULL) {
+ _zip_ef_free(ef);
+ return -1;
+ }
+ ef2->next = ef;
+ ef = ef2;
+ }
+ }
+
+ 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;
+
+ 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_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);
+ _zip_ef_free(ef);
+ 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;
+ }
+
+ 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_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
+
+ 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_needed));
+ _zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */
+ _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
+
+ _zip_u2d_time(de->last_mod, &dostime, &dosdate);
+ _zip_buffer_put_16(buffer, dostime);
+ _zip_buffer_put_16(buffer, dosdate);
+
+ _zip_buffer_put_32(buffer, de->crc);
+
+ if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
+ /* In local headers, if a ZIP64 EF is written, it MUST contain
+ * both compressed and uncompressed sizes (even if one of the
+ * two is smaller than 0xFFFFFFFF); on the other hand, those
+ * may only appear when the corresponding standard entry is
+ * 0xFFFFFFFF. (appnote.txt 4.5.3) */
+ _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
+ _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
+ }
+ else {
+ if (de->comp_size < ZIP_UINT32_MAX) {
+ _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
+ }
+ else {
+ _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
+ }
+ if (de->uncomp_size < ZIP_UINT32_MAX) {
+ _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
+ }
+ else {
+ _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
+ }
+ }
+
+ _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
+ /* TODO: check for overflow */
+ ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
+ _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
+
+ if ((flags & ZIP_FL_LOCAL) == 0) {
+ _zip_buffer_put_16(buffer, _zip_string_length(de->comment));
+ _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
+ _zip_buffer_put_16(buffer, de->int_attrib);
+ _zip_buffer_put_32(buffer, de->ext_attrib);
+ if (de->offset < ZIP_UINT32_MAX)
+ _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
+ else
+ _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
+ }
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(buffer);
+ _zip_ef_free(ef);
+ return -1;
+ }
+
+ if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
+ _zip_buffer_free(buffer);
+ _zip_ef_free(ef);
+ return -1;
+ }
+
+ _zip_buffer_free(buffer);
+
+ if (de->filename) {
+ if (_zip_string_write(za, de->filename) < 0) {
+ _zip_ef_free(ef);
+ return -1;
+ }
+ }
+
+ if (ef) {
+ if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
+ _zip_ef_free(ef);
+ return -1;
+ }
+ }
+ _zip_ef_free(ef);
+ if (de->extra_fields) {
+ if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
+ return -1;
+ }
+ }
+
+ if ((flags & ZIP_FL_LOCAL) == 0) {
+ if (de->comment) {
+ if (_zip_string_write(za, de->comment) < 0) {
+ return -1;
+ }
+ }
+ }
+
+
+ return is_zip64;
+}
+
+
+static time_t
+_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
+{
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(tm));
+
+ /* let mktime decide if DST is in effect */
+ tm.tm_isdst = -1;
+
+ 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;
+
+ return mktime(&tm);
+}
+
+
+static zip_extra_field_t *
+_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error)
+{
+ const zip_uint8_t *raw;
+ zip_uint32_t len;
+ zip_buffer_t *buffer;
+ zip_extra_field_t *ef;
+
+ if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
+ /* error already set */
+ 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) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ _zip_buffer_put_8(buffer, 1);
+ _zip_buffer_put_32(buffer, _zip_string_crc32(str));
+ _zip_buffer_put(buffer, raw, len);
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ _zip_buffer_free(buffer);
+ return NULL;
+ }
+
+ ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
+ _zip_buffer_free(buffer);
+
+ return ef;
+}
+
+
+zip_dirent_t *
+_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
+{
+ if (error == NULL)
+ error = &za->error;
+
+ if (idx >= za->nentry) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
+ if (za->entry[idx].orig == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
+ zip_error_set(error, ZIP_ER_DELETED, 0);
+ return NULL;
+ }
+ return za->entry[idx].orig;
+ }
+ else
+ return za->entry[idx].changes;
+}
+
+
+
+
+void
+_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate)
+{
+ struct tm *tm;
+
+ tm = localtime(&intime);
+ if (tm->tm_year < 80) {
+ tm->tm_year = 80;
+ }
+
+ *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
+ *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
+
+ return;
+}
diff --git a/src/Common/libzip/zip_discard.c b/src/Common/libzip/zip_discard.c
new file mode 100644
index 00000000..1876c84f
--- /dev/null
+++ b/src/Common/libzip/zip_discard.c
@@ -0,0 +1,79 @@
+/*
+ zip_discard.c -- discard and free struct zip
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+/* zip_discard:
+ frees the space allocated to a zipfile struct, and closes the
+ corresponding file. */
+
+void
+zip_discard(zip_t *za)
+{
+ zip_uint64_t i;
+
+ if (za == NULL)
+ return;
+
+ if (za->src) {
+ zip_source_close(za->src);
+ zip_source_free(za->src);
+ }
+
+ free(za->default_password);
+ _zip_string_free(za->comment_orig);
+ _zip_string_free(za->comment_changes);
+
+ _zip_hash_free(za->names);
+
+ if (za->entry) {
+ for (i=0; i<za->nentry; i++)
+ _zip_entry_finalize(za->entry+i);
+ free(za->entry);
+ }
+
+ for (i=0; i<za->nopen_source; i++) {
+ _zip_source_invalidate(za->open_source[i]);
+ }
+ free(za->open_source);
+
+ zip_error_fini(&za->error);
+
+ free(za);
+
+ return;
+}
diff --git a/src/Common/libzip/zip_entry.c b/src/Common/libzip/zip_entry.c
new file mode 100644
index 00000000..6f890068
--- /dev/null
+++ b/src/Common/libzip/zip_entry.c
@@ -0,0 +1,53 @@
+/*
+ zip_entry.c -- struct zip_entry helper functions
+ Copyright (C) 1999-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
+ 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"
+
+void
+_zip_entry_finalize(zip_entry_t *e)
+{
+ _zip_unchange_data(e);
+ _zip_dirent_free(e->orig);
+ _zip_dirent_free(e->changes);
+}
+
+
+void
+_zip_entry_init(zip_entry_t *e)
+{
+ e->orig = NULL;
+ e->changes = NULL;
+ e->source = NULL;
+ e->deleted = 0;
+}
diff --git a/src/Common/libzip/zip_err_str.c b/src/Common/libzip/zip_err_str.c
new file mode 100644
index 00000000..65698be0
--- /dev/null
+++ b/src/Common/libzip/zip_err_str.c
@@ -0,0 +1,80 @@
+/*
+ This file was generated automatically by ./make_zip_err_str.sh
+ from ./zip.h; make changes there.
+ */
+
+#include "zipint.h"
+
+const char * const _zip_err_str[] = {
+ "No error",
+ "Multi-disk zip archives not supported",
+ "Renaming temporary file failed",
+ "Closing zip archive failed",
+ "Seek error",
+ "Read error",
+ "Write error",
+ "CRC error",
+ "Containing zip archive was closed",
+ "No such file",
+ "File already exists",
+ "Can't open file",
+ "Failure to create temporary file",
+ "Zlib error",
+ "Malloc failure",
+ "Entry has been changed",
+ "Compression method not supported",
+ "Premature end of file",
+ "Invalid argument",
+ "Not a zip archive",
+ "Internal error",
+ "Zip archive inconsistent",
+ "Can't remove file",
+ "Entry has been deleted",
+ "Encryption method not supported",
+ "Read-only archive",
+ "No password provided",
+ "Wrong password provided",
+ "Operation not supported",
+ "Resource still in use",
+ "Tell error",
+};
+
+const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
+
+#define N ZIP_ET_NONE
+#define S ZIP_ET_SYS
+#define Z ZIP_ET_ZLIB
+
+const int _zip_err_type[] = {
+ N,
+ N,
+ S,
+ S,
+ S,
+ S,
+ S,
+ N,
+ N,
+ N,
+ N,
+ S,
+ S,
+ Z,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ S,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ N,
+ S,
+};
diff --git a/src/Common/libzip/zip_error.c b/src/Common/libzip/zip_error.c
new file mode 100644
index 00000000..43ddf4f9
--- /dev/null
+++ b/src/Common/libzip/zip_error.c
@@ -0,0 +1,155 @@
+/*
+ zip_error.c -- zip_error_t helper functions
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_error_code_system(const zip_error_t *error) {
+ return error->sys_err;
+}
+
+
+ZIP_EXTERN int
+zip_error_code_zip(const zip_error_t *error) {
+ return error->zip_err;
+}
+
+
+ZIP_EXTERN void
+zip_error_fini(zip_error_t *err)
+{
+ free(err->str);
+ err->str = NULL;
+}
+
+
+ZIP_EXTERN void
+zip_error_init(zip_error_t *err)
+{
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+ err->str = NULL;
+}
+
+ZIP_EXTERN void
+zip_error_init_with_code(zip_error_t *error, int ze)
+{
+ zip_error_init(error);
+ error->zip_err = ze;
+ switch (zip_error_system_type(error)) {
+ case ZIP_ET_SYS:
+ error->sys_err = errno;
+ break;
+
+ default:
+ error->sys_err = 0;
+ break;
+ }
+}
+
+
+ZIP_EXTERN int
+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_err_type[error->zip_err];
+}
+
+
+void
+_zip_error_clear(zip_error_t *err)
+{
+ if (err == NULL)
+ return;
+
+ err->zip_err = ZIP_ER_OK;
+ err->sys_err = 0;
+}
+
+
+void
+_zip_error_copy(zip_error_t *dst, const zip_error_t *src)
+{
+ dst->zip_err = src->zip_err;
+ dst->sys_err = src->sys_err;
+}
+
+
+void
+_zip_error_get(const zip_error_t *err, int *zep, int *sep)
+{
+ if (zep)
+ *zep = err->zip_err;
+ if (sep) {
+ if (zip_error_system_type(err) != ZIP_ET_NONE)
+ *sep = err->sys_err;
+ else
+ *sep = 0;
+ }
+}
+
+
+void
+zip_error_set(zip_error_t *err, int ze, int se)
+{
+ if (err) {
+ err->zip_err = ze;
+ err->sys_err = se;
+ }
+}
+
+
+void
+_zip_error_set_from_source(zip_error_t *err, zip_source_t *src)
+{
+ _zip_error_copy(err, zip_source_error(src));
+}
+
+
+zip_int64_t
+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;
+ }
+
+ e[0] = zip_error_code_zip(error);
+ e[1] = zip_error_code_system(error);
+ return sizeof(int)*2;
+}
diff --git a/src/Common/libzip/zip_error_clear.c b/src/Common/libzip/zip_error_clear.c
new file mode 100644
index 00000000..ec45e688
--- /dev/null
+++ b/src/Common/libzip/zip_error_clear.c
@@ -0,0 +1,45 @@
+/*
+ zip_error_clear.c -- clear zip error
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN void
+zip_error_clear(zip_t *za)
+{
+ if (za == NULL)
+ return;
+
+ _zip_error_clear(&za->error);
+}
diff --git a/src/Common/libzip/zip_error_get.c b/src/Common/libzip/zip_error_get.c
new file mode 100644
index 00000000..c2220189
--- /dev/null
+++ b/src/Common/libzip/zip_error_get.c
@@ -0,0 +1,57 @@
+/*
+ zip_error_get.c -- get zip error
+ Copyright (C) 1999-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN void
+zip_error_get(zip_t *za, int *zep, int *sep)
+{
+ _zip_error_get(&za->error, zep, sep);
+}
+
+
+ZIP_EXTERN zip_error_t *
+zip_get_error(zip_t *za)
+{
+ return &za->error;
+}
+
+
+ZIP_EXTERN zip_error_t *
+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
new file mode 100644
index 00000000..7e27bbf3
--- /dev/null
+++ b/src/Common/libzip/zip_error_get_sys_type.c
@@ -0,0 +1,45 @@
+/*
+ zip_error_get_sys_type.c -- return type of system error code
+ Copyright (C) 1999-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
+ 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.
+*/
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_error_get_sys_type(int ze)
+{
+ if (ze < 0 || ze >= _zip_nerr_str)
+ return 0;
+
+ return _zip_err_type[ze];
+}
diff --git a/src/Common/libzip/zip_error_strerror.c b/src/Common/libzip/zip_error_strerror.c
new file mode 100644
index 00000000..29efc8a9
--- /dev/null
+++ b/src/Common/libzip/zip_error_strerror.c
@@ -0,0 +1,87 @@
+/*
+ zip_error_sterror.c -- get string representation of struct zip_error
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN const char *
+zip_error_strerror(zip_error_t *err)
+{
+ const char *zs, *ss;
+ char buf[128], *s;
+
+ zip_error_fini(err);
+
+ if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) {
+ sprintf(buf, "Unknown error %d", err->zip_err);
+ zs = NULL;
+ ss = buf;
+ }
+ else {
+ zs = _zip_err_str[err->zip_err];
+
+ switch (_zip_err_type[err->zip_err]) {
+ case ZIP_ET_SYS:
+ ss = strerror(err->sys_err);
+ break;
+
+ case ZIP_ET_ZLIB:
+ ss = zError(err->sys_err);
+ break;
+
+ default:
+ ss = NULL;
+ }
+ }
+
+ if (ss == NULL)
+ return zs;
+ else {
+ 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);
+ err->str = s;
+
+ return s;
+ }
+}
diff --git a/src/Common/libzip/zip_error_to_str.c b/src/Common/libzip/zip_error_to_str.c
new file mode 100644
index 00000000..22de1778
--- /dev/null
+++ b/src/Common/libzip/zip_error_to_str.c
@@ -0,0 +1,68 @@
+/*
+ zip_error_to_str.c -- get string representation of zip error code
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
+{
+ const char *zs, *ss;
+
+ if (ze < 0 || ze >= _zip_nerr_str)
+ return snprintf(buf, len, "Unknown error %d", ze);
+
+ zs = _zip_err_str[ze];
+
+ switch (_zip_err_type[ze]) {
+ case ZIP_ET_SYS:
+ ss = strerror(se);
+ break;
+
+ case ZIP_ET_ZLIB:
+ ss = zError(se);
+ break;
+
+ default:
+ ss = NULL;
+ }
+
+ 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
new file mode 100644
index 00000000..03504782
--- /dev/null
+++ b/src/Common/libzip/zip_extra_field.c
@@ -0,0 +1,438 @@
+/*
+ zip_extra_field.c -- manipulate extra fields
+ Copyright (C) 2012-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>
+
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+zip_extra_field_t *
+_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;
+
+ ef = ef->next;
+ }
+
+ return head;
+}
+
+
+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_extra_field_t *head, *prev;
+ int i;
+
+ i = 0;
+ head = ef;
+ prev = NULL;
+ for (; ef; ef=(prev ? prev->next : head)) {
+ if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) {
+ if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
+ ef->flags &= ~(flags & ZIP_EF_BOTH);
+ if ((ef->flags & ZIP_EF_BOTH) == 0) {
+ if (prev)
+ prev->next = ef->next;
+ else
+ head = ef->next;
+ ef->next = NULL;
+ _zip_ef_free(ef);
+
+ if (id_idx == ZIP_EXTRA_FIELD_ALL)
+ continue;
+ }
+ }
+
+ i++;
+ if (i > id_idx)
+ break;
+ }
+ prev = ef;
+ }
+
+ return head;
+}
+
+
+
+void
+_zip_ef_free(zip_extra_field_t *ef)
+{
+ zip_extra_field_t *ef2;
+
+ while (ef) {
+ ef2 = ef->next;
+ free(ef->data);
+ free(ef);
+ ef = ef2;
+ }
+}
+
+
+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' };
+
+ int i;
+
+ i = 0;
+ for (; ef; ef=ef->next) {
+ if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
+ if (i < id_idx) {
+ i++;
+ continue;
+ }
+
+ if (lenp)
+ *lenp = ef->size;
+ if (ef->size > 0)
+ return ef->data;
+ else
+ return empty;
+ }
+ }
+
+ zip_error_set(error, ZIP_ER_NOENT, 0);
+ return NULL;
+}
+
+
+zip_extra_field_t *
+_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from)
+{
+ zip_extra_field_t *ef2, *tt, *tail;
+ int duplicate;
+
+ if (to == NULL)
+ return from;
+
+ for (tail=to; tail->next; tail=tail->next)
+ ;
+
+ for (; from; from=ef2) {
+ ef2 = from->next;
+
+ 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) {
+ tt->flags |= (from->flags & ZIP_EF_BOTH);
+ duplicate = 1;
+ break;
+ }
+ }
+
+ from->next = NULL;
+ if (duplicate)
+ _zip_ef_free(from);
+ else
+ tail = tail->next = from;
+ }
+
+ return to;
+}
+
+
+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_extra_field_t *ef;
+
+ if ((ef=(zip_extra_field_t *)malloc(sizeof(*ef))) == NULL)
+ return NULL;
+
+ ef->next = NULL;
+ ef->flags = flags;
+ ef->id = id;
+ ef->size = size;
+ if (size > 0) {
+ if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
+ free(ef);
+ return NULL;
+ }
+ }
+ else
+ ef->data = NULL;
+
+ return ef;
+}
+
+
+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_buffer_t *buffer;
+ zip_extra_field_t *ef, *ef2, *ef_head;
+
+ if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) {
+ 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);
+ flen = _zip_buffer_get_16(buffer);
+ ef_data = _zip_buffer_get(buffer, flen);
+
+ if (ef_data == NULL) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_buffer_free(buffer);
+ _zip_ef_free(ef_head);
+ return false;
+ }
+
+ if ((ef2=_zip_ef_new(fid, flen, ef_data, flags)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ _zip_buffer_free(buffer);
+ _zip_ef_free(ef_head);
+ return false;
+ }
+
+ if (ef_head) {
+ ef->next = ef2;
+ ef = ef2;
+ }
+ else
+ ef_head = ef = ef2;
+ }
+
+ if (!_zip_buffer_eof(buffer)) {
+ /* Android APK files align stored file data with padding in extra fields; ignore. */
+ /* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
+ size_t glen = _zip_buffer_left(buffer);
+ zip_uint8_t *garbage;
+ garbage = _zip_buffer_get(buffer, glen);
+ if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_buffer_free(buffer);
+ _zip_ef_free(ef_head);
+ return false;
+ }
+ }
+
+ _zip_buffer_free(buffer);
+
+ if (ef_head_p) {
+ *ef_head_p = ef_head;
+ }
+ else {
+ _zip_ef_free(ef_head);
+ }
+
+ return true;
+}
+
+
+zip_extra_field_t *
+_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;
+ }
+ }
+
+ return ef_head;
+}
+
+
+zip_uint16_t
+_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags)
+{
+ zip_uint16_t size;
+
+ size = 0;
+ for (; ef; ef=ef->next) {
+ if (ef->flags & flags & ZIP_EF_BOTH)
+ size = (zip_uint16_t)(size+4+ef->size);
+ }
+
+ return size;
+}
+
+
+int
+_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags)
+{
+ zip_uint8_t b[4];
+ zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b));
+
+ if (buffer == NULL) {
+ return -1;
+ }
+
+ 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_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_write(za, b, 4) < 0) {
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+ if (ef->size > 0) {
+ if (_zip_write(za, ef->data, ef->size) < 0) {
+ _zip_buffer_free(buffer);
+ return -1;
+ }
+ }
+ }
+ }
+
+ _zip_buffer_free(buffer);
+ return 0;
+}
+
+
+int
+_zip_read_local_ef(zip_t *za, zip_uint64_t idx)
+{
+ zip_entry_t *e;
+ unsigned char b[4];
+ zip_buffer_t *buffer;
+ zip_uint16_t fname_len, ef_len;
+
+ if (idx >= za->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ e = za->entry+idx;
+
+ if (e->orig == NULL || e->orig->local_extra_fields_read)
+ return 0;
+
+ if (e->orig->offset + 26 > ZIP_INT64_MAX) {
+ zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
+ return -1;
+ }
+
+ if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return -1;
+ }
+
+ if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
+ 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);
+
+ if (ef_len > 0) {
+ zip_extra_field_t *ef;
+ zip_uint8_t *ef_raw;
+
+ if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
+ zip_error_set(&za->error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+
+ ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);
+
+ if (ef_raw == NULL)
+ return -1;
+
+ if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
+ free(ef_raw);
+ return -1;
+ }
+ free(ef_raw);
+
+ if (ef) {
+ ef = _zip_ef_remove_internal(ef);
+ e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
+ }
+ }
+
+ e->orig->local_extra_fields_read = 1;
+
+ if (e->changes && e->changes->local_extra_fields_read == 0) {
+ e->changes->extra_fields = e->orig->extra_fields;
+ e->changes->local_extra_fields_read = 1;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_extra_field_api.c b/src/Common/libzip/zip_extra_field_api.c
new file mode 100644
index 00000000..ed93944a
--- /dev/null
+++ b/src/Common/libzip/zip_extra_field_api.c
@@ -0,0 +1,366 @@
+/*
+ zip_extra_field_api.c -- public extra fields API functions
+ Copyright (C) 2012-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
+ 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"
+
+
+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_dirent_t *de;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ return -1;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
+ 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);
+ return 0;
+}
+
+
+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_dirent_t *de;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ return -1;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
+ return -1;
+
+ de = za->entry[idx].changes;
+
+ de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
+ return 0;
+}
+
+
+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_dirent_t *de;
+ zip_extra_field_t *ef;
+ int i;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
+ return NULL;
+
+ if (flags & ZIP_FL_LOCAL)
+ if (_zip_read_local_ef(za, idx) < 0)
+ return NULL;
+
+ i = 0;
+ for (ef=de->extra_fields; ef; ef=ef->next) {
+ if (ef->flags & flags & ZIP_EF_BOTH) {
+ if (i < ef_idx) {
+ i++;
+ continue;
+ }
+
+ if (idp)
+ *idp = ef->id;
+ if (lenp)
+ *lenp = ef->size;
+ if (ef->size > 0)
+ return ef->data;
+ else
+ return empty;
+ }
+ }
+
+ zip_error_set(&za->error, ZIP_ER_NOENT, 0);
+ return NULL;
+
+}
+
+
+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_dirent_t *de;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
+ return NULL;
+
+ if (flags & ZIP_FL_LOCAL)
+ if (_zip_read_local_ef(za, idx) < 0)
+ return NULL;
+
+ return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
+}
+
+
+ZIP_EXTERN zip_int16_t
+zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
+{
+ zip_dirent_t *de;
+ zip_extra_field_t *ef;
+ zip_uint16_t n;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
+ return -1;
+
+ if (flags & ZIP_FL_LOCAL)
+ if (_zip_read_local_ef(za, idx) < 0)
+ return -1;
+
+ n = 0;
+ for (ef=de->extra_fields; ef; ef=ef->next)
+ if (ef->flags & flags & ZIP_EF_BOTH)
+ n++;
+
+ return (zip_int16_t)n;
+}
+
+
+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_dirent_t *de;
+ zip_extra_field_t *ef;
+ zip_uint16_t n;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
+ return -1;
+
+ if (flags & ZIP_FL_LOCAL)
+ if (_zip_read_local_ef(za, idx) < 0)
+ return -1;
+
+ n = 0;
+ for (ef=de->extra_fields; ef; ef=ef->next)
+ if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
+ n++;
+
+ return (zip_int16_t)n;
+}
+
+
+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_dirent_t *de;
+ zip_uint16_t ls, cs;
+ zip_extra_field_t *ef, *ef_prev, *ef_new;
+ int i, found, new_len;
+
+ if ((flags & ZIP_EF_BOTH) == 0) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ return -1;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (ZIP_EF_IS_INTERNAL(ef_id)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
+ return -1;
+
+ de = za->entry[idx].changes;
+
+ ef = de->extra_fields;
+ ef_prev = NULL;
+ i = 0;
+ found = 0;
+
+ for (; ef; ef=ef->next) {
+ if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
+ if (i == ef_idx) {
+ found = 1;
+ break;
+ }
+ i++;
+ }
+ ef_prev = ef;
+ }
+
+ if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (flags & ZIP_EF_LOCAL)
+ ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
+ else
+ ls = 0;
+ if (flags & ZIP_EF_CENTRAL)
+ cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
+ else
+ cs = 0;
+
+ new_len = ls > cs ? ls : cs;
+ if (found)
+ new_len -= ef->size + 4;
+ new_len += len + 4;
+
+ if (new_len > ZIP_UINT16_MAX) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ if (found) {
+ if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
+ ef_new->next = ef->next;
+ ef->next = NULL;
+ _zip_ef_free(ef);
+ if (ef_prev)
+ ef_prev->next = ef_new;
+ else
+ de->extra_fields = ef_new;
+ }
+ else {
+ ef->flags &= ~(flags & ZIP_EF_BOTH);
+ ef_new->next = ef->next;
+ ef->next = ef_new;
+ }
+ }
+ else if (ef_prev) {
+ ef_new->next = ef_prev->next;
+ ef_prev->next = ef_new;
+ }
+ else
+ de->extra_fields = ef_new;
+
+ return 0;
+}
+
+
+
+int
+_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;
+ }
+
+ e = za->entry+idx;
+
+ if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
+ return 0;
+
+ if (e->orig) {
+ if (_zip_read_local_ef(za, idx) < 0)
+ return -1;
+ }
+
+ 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->orig && e->orig->extra_fields) {
+ if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
+ return -1;
+ }
+ 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
new file mode 100644
index 00000000..25a201b1
--- /dev/null
+++ b/src/Common/libzip/zip_fclose.c
@@ -0,0 +1,55 @@
+/*
+ zip_fclose.c -- close file in zip archive
+ Copyright (C) 1999-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
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_fclose(zip_file_t *zf)
+{
+ int ret;
+
+ if (zf->src)
+ zip_source_free(zf->src);
+
+ ret = 0;
+ if (zf->error.zip_err)
+ ret = zf->error.zip_err;
+
+ zip_error_fini(&zf->error);
+ free(zf);
+ return ret;
+}
diff --git a/src/Common/libzip/zip_fdopen.c b/src/Common/libzip/zip_fdopen.c
new file mode 100644
index 00000000..bbcdf4f6
--- /dev/null
+++ b/src/Common/libzip/zip_fdopen.c
@@ -0,0 +1,85 @@
+/*
+ zip_fdopen.c -- open read-only archive from file descriptor
+ 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
+ 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"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+ZIP_EXTERN zip_t *
+zip_fdopen(int fd_orig, int _flags, int *zep)
+{
+ int fd;
+ FILE *fp;
+ zip_t *za;
+ zip_source_t *src;
+ struct zip_error error;
+
+ if (_flags < 0 || (_flags & ZIP_TRUNCATE)) {
+ _zip_set_open_error(zep, NULL, ZIP_ER_INVAL);
+ return NULL;
+ }
+
+ /* We dup() here to avoid messing with the passed in fd.
+ We could not restore it to the original state in case of error. */
+
+ if ((fd=dup(fd_orig)) < 0) {
+ _zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
+ return NULL;
+ }
+
+ if ((fp=fdopen(fd, "rb")) == NULL) {
+ close(fd);
+ _zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
+ return NULL;
+ }
+
+ zip_error_init(&error);
+ if ((src = zip_source_filep_create(fp, 0, -1, &error)) == NULL) {
+ _zip_set_open_error(zep, &error, 0);
+ zip_error_fini(&error);
+ return NULL;
+ }
+
+ if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
+ _zip_set_open_error(zep, &error, 0);
+ zip_error_fini(&error);
+ return NULL;
+ }
+
+ zip_error_fini(&error);
+ close(fd_orig);
+ return za;
+}
diff --git a/src/Common/libzip/zip_file_add.c b/src/Common/libzip/zip_file_add.c
new file mode 100644
index 00000000..9944c0f1
--- /dev/null
+++ b/src/Common/libzip/zip_file_add.c
@@ -0,0 +1,53 @@
+/*
+ zip_file_add.c -- add file via callback function
+ Copyright (C) 1999-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
+ 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"
+
+/*
+ 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.
+*/
+
+ZIP_EXTERN zip_int64_t
+zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags)
+{
+ if (name == NULL || source == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ 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
new file mode 100644
index 00000000..be454982
--- /dev/null
+++ b/src/Common/libzip/zip_file_error_clear.c
@@ -0,0 +1,45 @@
+/*
+ zip_file_error_clear.c -- clear zip file error
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN void
+zip_file_error_clear(zip_file_t *zf)
+{
+ if (zf == NULL)
+ return;
+
+ _zip_error_clear(&zf->error);
+}
diff --git a/src/Common/libzip/zip_file_error_get.c b/src/Common/libzip/zip_file_error_get.c
new file mode 100644
index 00000000..be764fd5
--- /dev/null
+++ b/src/Common/libzip/zip_file_error_get.c
@@ -0,0 +1,42 @@
+/*
+ zip_file_error_get.c -- get zip file error
+ Copyright (C) 1999-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
+ 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.
+*/
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN void
+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
new file mode 100644
index 00000000..55e7dc28
--- /dev/null
+++ b/src/Common/libzip/zip_file_get_comment.c
@@ -0,0 +1,56 @@
+/*
+ zip_file_get_comment.c -- get file comment
+ Copyright (C) 2006-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
+ 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"
+
+/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */
+
+ZIP_EXTERN const char *
+zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags)
+{
+ zip_dirent_t *de;
+ zip_uint32_t len;
+ const zip_uint8_t *str;
+
+ if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
+ return NULL;
+
+ if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL)
+ return NULL;
+
+ if (lenp)
+ *lenp = len;
+
+ return (const char *)str;
+}
diff --git a/src/Common/libzip/zip_file_get_external_attributes.c b/src/Common/libzip/zip_file_get_external_attributes.c
new file mode 100644
index 00000000..b6526cf2
--- /dev/null
+++ b/src/Common/libzip/zip_file_get_external_attributes.c
@@ -0,0 +1,51 @@
+/*
+ zip_file_get_external_attributes.c -- get opsys/external attributes
+ Copyright (C) 2013-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
+ 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"
+
+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_dirent_t *de;
+
+ if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
+ return -1;
+
+ if (opsys)
+ *opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff);
+
+ if (attributes)
+ *attributes = de->ext_attrib;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_file_get_offset.c b/src/Common/libzip/zip_file_get_offset.c
new file mode 100644
index 00000000..0257b042
--- /dev/null
+++ b/src/Common/libzip/zip_file_get_offset.c
@@ -0,0 +1,73 @@
+/*
+ zip_file_get_offset.c -- get offset of file data in archive.
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "zipint.h"
+
+
+/* _zip_file_get_offset(za, ze):
+ Returns the offset of the file data for entry ze.
+
+ On error, fills in za->error and returns 0.
+*/
+
+zip_uint64_t
+_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error)
+{
+ zip_uint64_t offset;
+ zip_int32_t size;
+
+ offset = za->entry[idx].orig->offset;
+
+ if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
+ _zip_error_set_from_source(error, za->src);
+ return 0;
+ }
+
+ /* TODO: cache? */
+ 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;
+ }
+
+ return offset + (zip_uint32_t)size;
+}
diff --git a/src/Common/libzip/zip_file_rename.c b/src/Common/libzip/zip_file_rename.c
new file mode 100644
index 00000000..4400938a
--- /dev/null
+++ b/src/Common/libzip/zip_file_rename.c
@@ -0,0 +1,68 @@
+/*
+ zip_file_rename.c -- rename file in zip archive
+ Copyright (C) 1999-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
+ 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 <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+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)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ 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] == '/');
+
+ if (new_is_dir != old_is_dir) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ return _zip_set_name(za, idx, name, flags);
+}
diff --git a/src/Common/libzip/zip_file_replace.c b/src/Common/libzip/zip_file_replace.c
new file mode 100644
index 00000000..e430efae
--- /dev/null
+++ b/src/Common/libzip/zip_file_replace.c
@@ -0,0 +1,108 @@
+/*
+ zip_file_replace.c -- replace file via callback function
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN int
+zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags)
+{
+ if (idx >= za->nentry || source == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (_zip_file_replace(za, idx, NULL, source, flags) == -1)
+ return -1;
+
+ return 0;
+}
+
+
+
+/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
+
+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_uint64_t za_nentry_prev;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ za_nentry_prev = za->nentry;
+ if (idx == ZIP_UINT64_MAX) {
+ zip_int64_t i = -1;
+
+ if (flags & ZIP_FL_OVERWRITE)
+ i = _zip_name_locate(za, name, flags, NULL);
+
+ if (i == -1) {
+ /* create and use new entry, used by zip_add */
+ if ((i=_zip_add_entry(za)) < 0)
+ return -1;
+ }
+ idx = (zip_uint64_t)i;
+ }
+
+ if (name && _zip_set_name(za, idx, name, flags) != 0) {
+ if (za->nentry != za_nentry_prev) {
+ _zip_entry_finalize(za->entry+idx);
+ za->nentry = za_nentry_prev;
+ }
+ return -1;
+ }
+
+ /* does not change any name related data, so we can do it here;
+ * needed for a double add of the same file name */
+ _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;
+ }
+
+ za->entry[idx].source = source;
+
+ return (zip_int64_t)idx;
+}
diff --git a/src/Common/libzip/zip_file_set_comment.c b/src/Common/libzip/zip_file_set_comment.c
new file mode 100644
index 00000000..e455fbd2
--- /dev/null
+++ b/src/Common/libzip/zip_file_set_comment.c
@@ -0,0 +1,103 @@
+/*
+ zip_file_set_comment.c -- set comment for file in archive
+ Copyright (C) 2006-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
+ 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>
+
+#include "zipint.h"
+
+
+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_entry_t *e;
+ zip_string_t *cstr;
+ int changed;
+
+ if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ return -1;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (len > 0 && comment == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
+ return -1;
+ if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
+ cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
+ }
+ else
+ cstr = NULL;
+
+ e = za->entry+idx;
+
+ if (e->changes) {
+ _zip_string_free(e->changes->comment);
+ e->changes->comment = NULL;
+ e->changes->changed &= ~ZIP_DIRENT_COMMENT;
+ }
+
+ if (e->orig && e->orig->comment)
+ changed = !_zip_string_equal(e->orig->comment, cstr);
+ else
+ 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);
+ _zip_string_free(cstr);
+ return -1;
+ }
+ }
+ e->changes->comment = cstr;
+ e->changes->changed |= ZIP_DIRENT_COMMENT;
+ }
+ else {
+ _zip_string_free(cstr);
+ if (e->changes && e->changes->changed == 0) {
+ _zip_dirent_free(e->changes);
+ e->changes = NULL;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_file_set_external_attributes.c b/src/Common/libzip/zip_file_set_external_attributes.c
new file mode 100644
index 00000000..b772c31e
--- /dev/null
+++ b/src/Common/libzip/zip_file_set_external_attributes.c
@@ -0,0 +1,83 @@
+/*
+ zip_file_set_external_attributes.c -- set external attributes for entry
+ Copyright (C) 2013-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
+ 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"
+
+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_entry_t *e;
+ int changed;
+ zip_uint8_t unchanged_opsys;
+ zip_uint32_t unchanged_attributes;
+
+ if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+ return -1;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ e = za->entry+idx;
+
+ 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;
+
+ changed = (opsys != unchanged_opsys || attributes != unchanged_attributes);
+
+ 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));
+ e->changes->ext_attrib = attributes;
+ e->changes->changed |= ZIP_DIRENT_ATTRIBUTES;
+ }
+ else if (e->changes) {
+ e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES;
+ if (e->changes->changed == 0) {
+ _zip_dirent_free(e->changes);
+ e->changes = NULL;
+ }
+ else {
+ e->changes->version_madeby = (zip_uint16_t)((unchanged_opsys << 8) | (e->changes->version_madeby & 0xff));
+ e->changes->ext_attrib = unchanged_attributes;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_file_set_mtime.c b/src/Common/libzip/zip_file_set_mtime.c
new file mode 100644
index 00000000..0cdd31a6
--- /dev/null
+++ b/src/Common/libzip/zip_file_set_mtime.c
@@ -0,0 +1,74 @@
+/*
+ zip_file_set_mtime.c -- set modification time of entry.
+ 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
+ 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"
+
+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;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ e = za->entry+idx;
+
+ changed = e->orig == NULL || mtime != e->orig->last_mod;
+
+ if (changed) {
+ if (e->changes == NULL) {
+ if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ }
+ e->changes->last_mod = mtime;
+ e->changes->changed |= ZIP_DIRENT_LAST_MOD;
+ }
+ else {
+ if (e->changes) {
+ e->changes->changed &= ~ZIP_DIRENT_LAST_MOD;
+ if (e->changes->changed == 0) {
+ _zip_dirent_free(e->changes);
+ e->changes = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_file_strerror.c b/src/Common/libzip/zip_file_strerror.c
new file mode 100644
index 00000000..8366f1ea
--- /dev/null
+++ b/src/Common/libzip/zip_file_strerror.c
@@ -0,0 +1,42 @@
+/*
+ zip_file_sterror.c -- get string representation of zip file error
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN const char *
+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
new file mode 100644
index 00000000..f2a27fab
--- /dev/null
+++ b/src/Common/libzip/zip_filerange_crc.c
@@ -0,0 +1,76 @@
+/*
+ zip_filerange_crc.c -- compute CRC32 for a range of a file
+ Copyright (C) 2008-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>
+
+ 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 <stdio.h>
+
+#include "zipint.h"
+
+
+
+int
+_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error)
+{
+ Bytef buf[BUFSIZE];
+ zip_int64_t n;
+
+ *crcp = crc32(0L, Z_NULL, 0);
+
+ if (start > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_SEEK, EFBIG);
+ return -1;
+ }
+
+ if (zip_source_seek(src, (zip_int64_t)start, SEEK_SET) != 0) {
+ _zip_error_set_from_source(error, src);
+ return -1;
+ }
+
+ while (len > 0) {
+ n = (zip_int64_t)(len > BUFSIZE ? BUFSIZE : len);
+ if ((n = zip_source_read(src, buf, (zip_uint64_t)n)) < 0) {
+ _zip_error_set_from_source(error, src);
+ return -1;
+ }
+ if (n == 0) {
+ zip_error_set(error, ZIP_ER_EOF, 0);
+ return -1;
+ }
+
+ *crcp = crc32(*crcp, buf, (uInt)n);
+
+ len -= (zip_uint64_t)n;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_fopen.c b/src/Common/libzip/zip_fopen.c
new file mode 100644
index 00000000..3adb5de6
--- /dev/null
+++ b/src/Common/libzip/zip_fopen.c
@@ -0,0 +1,47 @@
+/*
+ zip_fopen.c -- open file in zip archive for reading
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN zip_file_t *
+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)
+ return NULL;
+
+ return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password);
+}
diff --git a/src/Common/libzip/zip_fopen_encrypted.c b/src/Common/libzip/zip_fopen_encrypted.c
new file mode 100644
index 00000000..5eaf2b04
--- /dev/null
+++ b/src/Common/libzip/zip_fopen_encrypted.c
@@ -0,0 +1,47 @@
+/*
+ zip_fopen_encrypted.c -- open file for reading with password
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN zip_file_t *
+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)
+ return NULL;
+
+ return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password);
+}
diff --git a/src/Common/libzip/zip_fopen_index.c b/src/Common/libzip/zip_fopen_index.c
new file mode 100644
index 00000000..7496f982
--- /dev/null
+++ b/src/Common/libzip/zip_fopen_index.c
@@ -0,0 +1,45 @@
+/*
+ zip_fopen_index.c -- open file in zip archive for reading by index
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN zip_file_t *
+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
new file mode 100644
index 00000000..92258e85
--- /dev/null
+++ b/src/Common/libzip/zip_fopen_index_encrypted.c
@@ -0,0 +1,86 @@
+/*
+ zip_fopen_index_encrypted.c -- open file for reading by index w/ password
+ 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>
+
+ 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 <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+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_file_t *zf;
+ zip_source_t *src;
+
+ if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL)
+ return NULL;
+
+ if (zip_source_open(src) < 0) {
+ _zip_error_set_from_source(&za->error, src);
+ zip_source_free(src);
+ return NULL;
+ }
+
+ if ((zf=_zip_file_new(za)) == NULL) {
+ zip_source_free(src);
+ return NULL;
+ }
+
+ zf->src = src;
+
+ return zf;
+}
+
+
+static zip_file_t *
+_zip_file_new(zip_t *za)
+{
+ zip_file_t *zf;
+
+ if ((zf=(zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ zf->za = za;
+ zip_error_init(&zf->error);
+ zf->eof = 0;
+ zf->src = NULL;
+
+ return zf;
+}
diff --git a/src/Common/libzip/zip_fread.c b/src/Common/libzip/zip_fread.c
new file mode 100644
index 00000000..9c1cbe0c
--- /dev/null
+++ b/src/Common/libzip/zip_fread.c
@@ -0,0 +1,63 @@
+/*
+ zip_fread.c -- read from file
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN zip_int64_t
+zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread)
+{
+ zip_int64_t n;
+
+ if (!zf)
+ return -1;
+
+ if (zf->error.zip_err != 0)
+ return -1;
+
+ if (toread > ZIP_INT64_MAX) {
+ zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if ((zf->eof) || (toread == 0))
+ return 0;
+
+ if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
+ _zip_error_set_from_source(&zf->error, zf->src);
+ return -1;
+ }
+
+ return n;
+}
diff --git a/src/Common/libzip/zip_get_archive_comment.c b/src/Common/libzip/zip_get_archive_comment.c
new file mode 100644
index 00000000..78f8ca09
--- /dev/null
+++ b/src/Common/libzip/zip_get_archive_comment.c
@@ -0,0 +1,59 @@
+/*
+ zip_get_archive_comment.c -- get archive comment
+ Copyright (C) 2006-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
+ 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 <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN const char *
+zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags)
+{
+ zip_string_t *comment;
+ zip_uint32_t len;
+ const zip_uint8_t *str;
+
+ if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL))
+ comment = za->comment_orig;
+ else
+ comment = za->comment_changes;
+
+ if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL)
+ return NULL;
+
+ if (lenp)
+ *lenp = (int)len;
+
+ return (const char *)str;
+}
diff --git a/src/Common/libzip/zip_get_archive_flag.c b/src/Common/libzip/zip_get_archive_flag.c
new file mode 100644
index 00000000..bffe10c1
--- /dev/null
+++ b/src/Common/libzip/zip_get_archive_flag.c
@@ -0,0 +1,46 @@
+/*
+ zip_get_archive_flag.c -- get archive global flag
+ Copyright (C) 2008-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
+ 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"
+
+
+ZIP_EXTERN int
+zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags)
+{
+ unsigned int fl;
+
+ fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
+
+ return (fl & flag) ? 1 : 0;
+}
diff --git a/src/Common/libzip/zip_get_compression_implementation.c b/src/Common/libzip/zip_get_compression_implementation.c
new file mode 100644
index 00000000..c1120d3e
--- /dev/null
+++ b/src/Common/libzip/zip_get_compression_implementation.c
@@ -0,0 +1,44 @@
+/*
+ zip_get_compression_implementation.c -- get compression implementation
+ 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
+ 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"
+
+
+zip_compression_implementation
+_zip_get_compression_implementation(zip_int32_t cm)
+{
+ if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm))
+ return zip_source_deflate;
+ return NULL;
+}
diff --git a/src/Common/libzip/zip_get_encryption_implementation.c b/src/Common/libzip/zip_get_encryption_implementation.c
new file mode 100644
index 00000000..e2f833b4
--- /dev/null
+++ b/src/Common/libzip/zip_get_encryption_implementation.c
@@ -0,0 +1,44 @@
+/*
+ zip_get_encryption_implementation.c -- get encryption implementation
+ 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
+ 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"
+
+
+zip_encryption_implementation
+_zip_get_encryption_implementation(zip_uint16_t em)
+{
+ if (em == ZIP_EM_TRAD_PKWARE)
+ return zip_source_pkware;
+ return NULL;
+}
diff --git a/src/Common/libzip/zip_get_file_comment.c b/src/Common/libzip/zip_get_file_comment.c
new file mode 100644
index 00000000..d5f50bf2
--- /dev/null
+++ b/src/Common/libzip/zip_get_file_comment.c
@@ -0,0 +1,51 @@
+/*
+ zip_get_file_comment.c -- get file comment
+ Copyright (C) 2006-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN const char *
+zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags)
+{
+ zip_uint32_t len;
+ const char *s;
+
+ if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) {
+ if (lenp)
+ *lenp = (int)len;
+ }
+
+ return s;
+}
diff --git a/src/Common/libzip/zip_get_name.c b/src/Common/libzip/zip_get_name.c
new file mode 100644
index 00000000..d29e6365
--- /dev/null
+++ b/src/Common/libzip/zip_get_name.c
@@ -0,0 +1,60 @@
+/*
+ zip_get_name.c -- get filename for a file in zip file
+ Copyright (C) 1999-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
+ 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 <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN const char *
+zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
+{
+ return _zip_get_name(za, idx, flags, &za->error);
+}
+
+
+const char *
+_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
+{
+ zip_dirent_t *de;
+ const zip_uint8_t *str;
+
+ if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL)
+ return NULL;
+
+ if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL)
+ return NULL;
+
+ return (const char *)str;
+}
diff --git a/src/Common/libzip/zip_get_num_entries.c b/src/Common/libzip/zip_get_num_entries.c
new file mode 100644
index 00000000..c8644a4c
--- /dev/null
+++ b/src/Common/libzip/zip_get_num_entries.c
@@ -0,0 +1,53 @@
+/*
+ zip_get_num_entries.c -- get number of entries in archive
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN zip_int64_t
+zip_get_num_entries(zip_t *za, zip_flags_t flags)
+{
+ zip_uint64_t n;
+
+ if (za == NULL)
+ return -1;
+
+ if (flags & ZIP_FL_UNCHANGED) {
+ n = za->nentry;
+ while (n>0 && za->entry[n-1].orig == NULL)
+ --n;
+ return (zip_int64_t)n;
+ }
+ return (zip_int64_t)za->nentry;
+}
diff --git a/src/Common/libzip/zip_get_num_files.c b/src/Common/libzip/zip_get_num_files.c
new file mode 100644
index 00000000..cf96353f
--- /dev/null
+++ b/src/Common/libzip/zip_get_num_files.c
@@ -0,0 +1,52 @@
+/*
+ zip_get_num_files.c -- get number of files in archive
+ Copyright (C) 1999-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+#include <limits.h>
+
+
+ZIP_EXTERN int
+zip_get_num_files(zip_t *za)
+{
+ if (za == NULL)
+ return -1;
+
+ if (za->nentry > INT_MAX) {
+ zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0);
+ return -1;
+ }
+
+ return (int)za->nentry;
+}
diff --git a/src/Common/libzip/zip_hash.c b/src/Common/libzip/zip_hash.c
new file mode 100644
index 00000000..23f9708d
--- /dev/null
+++ b/src/Common/libzip/zip_hash.c
@@ -0,0 +1,267 @@
+/*
+ zip_hash.c -- hash table string -> uint64
+ Copyright (C) 2015-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.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "zipint.h"
+
+struct zip_hash_entry {
+ const zip_uint8_t *name;
+ zip_int64_t orig_index;
+ zip_int64_t current_index;
+ struct zip_hash_entry *next;
+};
+typedef struct zip_hash_entry zip_hash_entry_t;
+
+struct zip_hash {
+ zip_uint16_t table_size;
+ zip_hash_entry_t **table;
+};
+
+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;
+ }
+
+ if ((hash=(zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+ hash->table_size = table_size;
+ if ((hash->table=(zip_hash_entry_t**)calloc(table_size, sizeof(zip_hash_entry_t *))) == NULL) {
+ free(hash);
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ return hash;
+}
+
+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;
+
+ if (hash == NULL) {
+ return;
+ }
+
+ for (i=0; i<hash->table_size; i++) {
+ if (hash->table[i] != NULL) {
+ _free_list(hash->table[i]);
+ }
+ }
+ free(hash->table);
+ free(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;
+}
+
+/* insert into hash, return error on existence or memory issues */
+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_entry_t *entry;
+
+ if (hash == NULL || name == NULL || index > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return false;
+ }
+
+ 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) && entry->orig_index != -1) || entry->current_index != -1) {
+ zip_error_set(error, ZIP_ER_EXISTS, 0);
+ return false;
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ if (entry == NULL) {
+ if ((entry=(zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return false;
+ }
+ entry->name = name;
+ entry->next = hash->table[hash_value];
+ hash->table[hash_value] = entry;
+ entry->orig_index = -1;
+ }
+
+ if (flags & ZIP_FL_UNCHANGED) {
+ entry->orig_index = (zip_int64_t)index;
+ }
+ entry->current_index = (zip_int64_t)index;
+
+ return true;
+}
+
+/* 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_entry_t *entry, *previous;
+
+ if (hash == NULL || name == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return false;
+ }
+
+ 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;
+ }
+ else {
+ hash->table[hash_value] = entry->next;
+ }
+ free(entry);
+ }
+ else {
+ entry->current_index = -1;
+ }
+ return true;
+ }
+ previous = entry;
+ entry = entry->next;
+ };
+
+ zip_error_set(error, ZIP_ER_NOENT, 0);
+ return false;
+}
+
+/* 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_entry_t *entry;
+
+ if (hash == NULL || name == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ 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;
+ }
+ }
+ else {
+ if (entry->current_index != -1) {
+ return entry->current_index;
+ }
+ }
+ break;
+ }
+ }
+
+ zip_error_set(error, ZIP_ER_NOENT, 0);
+ return -1;
+}
+
+void
+_zip_hash_revert(zip_hash_t *hash)
+{
+ zip_uint16_t i;
+ zip_hash_entry_t *entry, *previous;
+
+ for (i = 0; i < hash->table_size; i++) {
+ previous = NULL;
+ entry = hash->table[i];
+ while (entry) {
+ if (entry->orig_index == -1) {
+ zip_hash_entry_t *p;
+ if (previous) {
+ previous->next = entry->next;
+ }
+ else {
+ hash->table[i] = entry->next;
+ }
+ p = entry;
+ entry = entry->next;
+ /* previous does not change */
+ free(p);
+ }
+ else {
+ entry->current_index = entry->orig_index;
+ previous = entry;
+ entry = entry->next;
+ }
+ }
+ }
+}
diff --git a/src/Common/libzip/zip_io_util.c b/src/Common/libzip/zip_io_util.c
new file mode 100644
index 00000000..b16927de
--- /dev/null
+++ b/src/Common/libzip/zip_io_util.c
@@ -0,0 +1,138 @@
+/*
+ zip_io_util.c -- I/O helper functions
+ 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>
+
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+int
+_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error)
+{
+ zip_int64_t n;
+
+ if (length > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+
+ if ((n = zip_source_read(src, b, length)) < 0) {
+ _zip_error_set_from_source(error, src);
+ return -1;
+ }
+
+ if (n < (zip_int64_t)length) {
+ zip_error_set(error, ZIP_ER_EOF, 0);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+zip_uint8_t *
+_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) {
+ return NULL;
+ }
+
+ r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
+ if (!r) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ 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;
+ }
+ memcpy(r, data, length);
+ }
+ else {
+ if (_zip_read(src, r, length, error) < 0) {
+ free(r);
+ return NULL;
+ }
+ }
+
+ if (nulp) {
+ zip_uint8_t *o;
+ /* replace any in-string NUL characters with spaces */
+ r[length] = 0;
+ for (o=r; o<r+length; o++)
+ if (*o == '\0')
+ *o = ' ';
+ }
+
+ return r;
+}
+
+
+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_uint8_t *raw;
+ zip_string_t *s;
+
+ if ((raw=_zip_read_data(buffer, src, len, nulp, error)) == NULL)
+ return NULL;
+
+ s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error);
+ free(raw);
+ return s;
+}
+
+
+int
+_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;
+ }
+ if ((zip_uint64_t)n != length) {
+ 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
new file mode 100644
index 00000000..cc6d767d
--- /dev/null
+++ b/src/Common/libzip/zip_memdup.c
@@ -0,0 +1,57 @@
+/*
+ zip_memdup.c -- internal zip function, "strdup" with len
+ Copyright (C) 1999-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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+void *
+_zip_memdup(const void *mem, size_t len, zip_error_t *error)
+{
+ void *ret;
+
+ if (len == 0)
+ return NULL;
+
+ ret = malloc(len);
+ if (!ret) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ memcpy(ret, mem, len);
+
+ return ret;
+}
diff --git a/src/Common/libzip/zip_name_locate.c b/src/Common/libzip/zip_name_locate.c
new file mode 100644
index 00000000..50ca40b1
--- /dev/null
+++ b/src/Common/libzip/zip_name_locate.c
@@ -0,0 +1,94 @@
+/*
+ zip_name_locate.c -- get index by name
+ 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>
+
+ 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 <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "zipint.h"
+
+
+ZIP_EXTERN zip_int64_t
+zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags)
+{
+ return _zip_name_locate(za, fname, flags, &za->error);
+}
+
+
+zip_int64_t
+_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error)
+{
+ int (*cmp)(const char *, const char *);
+ const char *fn, *p;
+ zip_uint64_t i;
+
+ if (za == NULL)
+ return -1;
+
+ if (fname == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (flags & (ZIP_FL_NOCASE|ZIP_FL_NODIR|ZIP_FL_ENC_CP437)) {
+ /* can't use hash table */
+ cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
+
+ for (i=0; i<za->nentry; i++) {
+ fn = _zip_get_name(za, i, flags, error);
+
+ /* newly added (partially filled) entry or error */
+ if (fn == NULL)
+ continue;
+
+ if (flags & ZIP_FL_NODIR) {
+ p = strrchr(fn, '/');
+ if (p)
+ fn = p+1;
+ }
+
+ if (cmp(fname, fn) == 0) {
+ _zip_error_clear(error);
+ return (zip_int64_t)i;
+ }
+ }
+
+ zip_error_set(error, ZIP_ER_NOENT, 0);
+ return -1;
+ }
+ else {
+ return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error);
+ }
+}
diff --git a/src/Common/libzip/zip_new.c b/src/Common/libzip/zip_new.c
new file mode 100644
index 00000000..562dd76a
--- /dev/null
+++ b/src/Common/libzip/zip_new.c
@@ -0,0 +1,74 @@
+/*
+ zip_new.c -- create and init struct zip
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+/* _zip_new:
+ creates a new zipfile struct, and sets the contents to zero; returns
+ the new struct. */
+
+zip_t *
+_zip_new(zip_error_t *error)
+{
+ zip_t *za;
+
+ za = (zip_t *)malloc(sizeof(struct zip));
+ if (!za) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((za->names = _zip_hash_new(ZIP_HASH_TABLE_SIZE, error)) == NULL) {
+ free(za);
+ return NULL;
+ }
+
+ za->src = NULL;
+ za->open_flags = 0;
+ zip_error_init(&za->error);
+ za->flags = za->ch_flags = 0;
+ za->default_password = NULL;
+ za->comment_orig = za->comment_changes = NULL;
+ za->comment_changed = 0;
+ za->nentry = za->nentry_alloc = 0;
+ za->entry = NULL;
+ za->nopen_source = za->nopen_source_alloc = 0;
+ za->open_source = NULL;
+ za->tempdir = NULL;
+
+ return za;
+}
diff --git a/src/Common/libzip/zip_open.c b/src/Common/libzip/zip_open.c
new file mode 100644
index 00000000..d6209ee1
--- /dev/null
+++ b/src/Common/libzip/zip_open.c
@@ -0,0 +1,853 @@
+/*
+ zip_open.c -- open zip archive by name
+ 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>
+
+ 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 <sys/stat.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+typedef enum {
+ EXISTS_ERROR = -1,
+ EXISTS_NOT = 0,
+ EXISTS_EMPTY,
+ EXISTS_NONEMPTY,
+} exists_t;
+static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
+static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
+static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
+static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
+static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
+static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
+static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
+static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
+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_EXTERN zip_t *
+zip_open(const char *fn, int _flags, int *zep)
+{
+ zip_t *za;
+ zip_source_t *src;
+ struct zip_error error;
+
+ zip_error_init(&error);
+ if ((src = zip_source_file_create(fn, 0, -1, &error)) == NULL) {
+ _zip_set_open_error(zep, &error, 0);
+ zip_error_fini(&error);
+ return NULL;
+ }
+
+ if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
+ zip_source_free(src);
+ _zip_set_open_error(zep, &error, 0);
+ zip_error_fini(&error);
+ return NULL;
+ }
+
+ zip_error_fini(&error);
+ return za;
+}
+
+
+ZIP_EXTERN zip_t *
+zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
+{
+ static zip_int64_t needed_support_read = -1;
+ static zip_int64_t needed_support_write = -1;
+
+ unsigned int flags;
+ zip_int64_t supported;
+ exists_t exists;
+
+ if (_flags < 0 || src == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ flags = (unsigned int)_flags;
+
+ supported = zip_source_supports(src);
+ 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);
+ }
+ if ((supported & needed_support_read) != needed_support_read) {
+ zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
+ return NULL;
+ }
+ if ((supported & needed_support_write) != needed_support_write) {
+ flags |= ZIP_RDONLY;
+ }
+
+ if ((flags & (ZIP_RDONLY|ZIP_TRUNCATE)) == (ZIP_RDONLY|ZIP_TRUNCATE)) {
+ zip_error_set(error, ZIP_ER_RDONLY, 0);
+ return NULL;
+ }
+
+ exists = _zip_file_exists(src, error);
+ switch (exists) {
+ case EXISTS_ERROR:
+ return NULL;
+
+ case EXISTS_NOT:
+ if ((flags & ZIP_CREATE) == 0) {
+ zip_error_set(error, ZIP_ER_NOENT, 0);
+ return NULL;
+ }
+ return _zip_allocate_new(src, flags, error);
+
+ default: {
+ zip_t *za;
+ if (flags & ZIP_EXCL) {
+ zip_error_set(error, ZIP_ER_EXISTS, 0);
+ return NULL;
+ }
+ if (zip_source_open(src) < 0) {
+ _zip_error_set_from_source(error, src);
+ return NULL;
+ }
+
+ if (flags & ZIP_TRUNCATE) {
+ za = _zip_allocate_new(src, flags, error);
+ }
+ else {
+ /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */
+ za = _zip_open(src, flags, error);
+ }
+
+ if (za == NULL) {
+ zip_source_close(src);
+ return NULL;
+ }
+ return za;
+ }
+ }
+}
+
+ZIP_EXTERN int
+zip_archive_set_tempdir(zip_t *za, const char *tempdir)
+{
+ char *new_tempdir;
+
+ if (tempdir) {
+ if ((new_tempdir = strdup(tempdir)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
+ return -1;
+ }
+ }
+ else
+ new_tempdir = NULL;
+
+ free(za->tempdir);
+ za->tempdir = new_tempdir;
+
+ return 0;
+}
+
+zip_t *
+_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
+{
+ zip_t *za;
+ zip_cdir_t *cdir;
+ struct zip_stat st;
+ zip_uint64_t len, idx;
+
+ zip_stat_init(&st);
+ if (zip_source_stat(src, &st) < 0) {
+ _zip_error_set_from_source(error, src);
+ return NULL;
+ }
+ if ((st.valid & ZIP_STAT_SIZE) == 0) {
+ zip_error_set(error, ZIP_ER_SEEK, EOPNOTSUPP);
+ return NULL;
+ }
+ len = st.size;
+
+ /* treat empty files as empty archives */
+ if (len == 0) {
+ if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
+ zip_source_free(src);
+ return NULL;
+ }
+
+ return za;
+ }
+
+ if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
+ return NULL;
+ }
+
+ if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
+ _zip_error_copy(error, &za->error);
+ /* keep src so discard does not get rid of it */
+ zip_source_keep(src);
+ zip_discard(za);
+ return NULL;
+ }
+
+ za->entry = cdir->entry;
+ za->nentry = cdir->nentry;
+ za->nentry_alloc = cdir->nentry_alloc;
+ za->comment_orig = cdir->comment;
+
+ free(cdir);
+
+ for (idx = 0; idx < za->nentry; idx++) {
+ const zip_uint8_t *name = _zip_string_get(za->entry[idx].orig->filename, NULL, 0, error);
+ if (name == NULL) {
+ /* keep src so discard does not get rid of it */
+ zip_source_keep(src);
+ zip_discard(za);
+ return NULL;
+ }
+
+ if (_zip_hash_add(za->names, name, idx, ZIP_FL_UNCHANGED, &za->error) == false) {
+ if (za->error.zip_err != ZIP_ER_EXISTS || (flags & ZIP_CHECKCONS)) {
+ _zip_error_copy(error, &za->error);
+ /* keep src so discard does not get rid of it */
+ zip_source_keep(src);
+ zip_discard(za);
+ return NULL;
+ }
+ }
+ }
+
+ za->ch_flags = za->flags;
+
+ return za;
+}
+
+
+void
+_zip_set_open_error(int *zep, const zip_error_t *err, int ze)
+{
+ if (err) {
+ ze = zip_error_code_zip(err);
+ if (zip_error_system_type(err) == ZIP_ET_SYS) {
+ errno = zip_error_code_system(err);
+ }
+ }
+
+ if (zep)
+ *zep = ze;
+}
+
+
+/* _zip_readcdir:
+ tries to find a valid end-of-central-directory at the beginning of
+ buf, and then the corresponding central directory entries.
+ Returns a struct zip_cdir which contains the central directory
+ entries, or NULL if unsuccessful. */
+
+static zip_cdir_t *
+_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error)
+{
+ zip_cdir_t *cd;
+ zip_uint16_t comment_len;
+ zip_uint64_t i, left;
+ zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
+ zip_buffer_t *cd_buffer;
+
+ if (_zip_buffer_left(buffer) < EOCDLEN) {
+ /* not enough bytes left for comment */
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ /* check for end-of-central-dir magic */
+ if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ 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);
+ }
+ else {
+ _zip_buffer_set_offset(buffer, eocd_offset);
+ cd = _zip_read_eocd(buffer, buf_offset, za->flags, error);
+ }
+
+ if (cd == NULL)
+ return NULL;
+
+ _zip_buffer_set_offset(buffer, eocd_offset + 20);
+ comment_len = _zip_buffer_get_16(buffer);
+
+ if (cd->offset + cd->size > buf_offset + eocd_offset) {
+ /* cdir spans past EOCD record */
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+
+ if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
+ zip_uint64_t tail_len;
+
+ _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 (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 (cd->offset >= buf_offset) {
+ 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;
+ }
+ }
+ else {
+ 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;
+ }
+
+ /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
+ if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+ }
+
+ left = (zip_uint64_t)cd->size;
+ i=0;
+ while (i<cd->nentry && left > 0) {
+ zip_int64_t entry_size;
+ 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) {
+ _zip_cdir_free(cd);
+ _zip_buffer_free(cd_buffer);
+ return NULL;
+ }
+ i++;
+ left -= (zip_uint64_t)entry_size;
+ }
+
+ if (i != cd->nentry) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_buffer_free(cd_buffer);
+ _zip_cdir_free(cd);
+ return NULL;
+ }
+
+ 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;
+ }
+ }
+
+ _zip_buffer_free(cd_buffer);
+ return cd;
+}
+
+
+/* _zip_checkcons:
+ Checks the consistency of the central directory by comparing central
+ directory entries with local headers and checking for plausible
+ file and header offsets. Returns -1 if not plausible, else the
+ difference between the lowest and the highest fileposition reached */
+
+static zip_int64_t
+_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
+{
+ zip_uint64_t i;
+ zip_uint64_t min, max, j;
+ struct zip_dirent temp;
+
+ _zip_dirent_init(&temp);
+ if (cd->nentry) {
+ max = cd->entry[0].orig->offset;
+ min = cd->entry[0].orig->offset;
+ }
+ else
+ min = max = 0;
+
+ for (i=0; i<cd->nentry; i++) {
+ if (cd->entry[i].orig->offset < min)
+ min = cd->entry[i].orig->offset;
+ if (min > (zip_uint64_t)cd->offset) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return -1;
+ }
+
+ j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
+ + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
+ if (j > max)
+ max = j;
+ if (max > (zip_uint64_t)cd->offset) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ 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;
+ }
+
+ if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
+ _zip_dirent_finalize(&temp);
+ return -1;
+ }
+
+ if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ _zip_dirent_finalize(&temp);
+ return -1;
+ }
+
+ cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
+ cd->entry[i].orig->local_extra_fields_read = 1;
+ temp.extra_fields = NULL;
+
+ _zip_dirent_finalize(&temp);
+ }
+
+ return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
+}
+
+
+/* _zip_headercomp:
+ compares a central directory entry and a local file header
+ Return 0 if they are consistent, -1 if not. */
+
+static int
+_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local)
+{
+ if ((central->version_needed != local->version_needed)
+#if 0
+ /* some zip-files have different values in local
+ and global headers for the bitflags */
+ || (central->bitflags != local->bitflags)
+#endif
+ || (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)) {
+ /* 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))
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static zip_t *
+_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error)
+{
+ zip_t *za;
+
+ if ((za = _zip_new(error)) == NULL) {
+ return NULL;
+ }
+
+ za->src = src;
+ za->open_flags = flags;
+ if (flags & ZIP_RDONLY) {
+ za->flags |= ZIP_AFL_RDONLY;
+ za->ch_flags |= ZIP_AFL_RDONLY;
+ }
+ return za;
+}
+
+
+/*
+ * tests for file existence
+ */
+static exists_t
+_zip_file_exists(zip_source_t *src, zip_error_t *error)
+{
+ struct zip_stat st;
+
+ zip_stat_init(&st);
+ 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) {
+ return EXISTS_NOT;
+ }
+ _zip_error_copy(error, src_error);
+ return EXISTS_ERROR;
+ }
+
+ return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY;
+}
+
+
+static zip_cdir_t *
+_zip_find_central_dir(zip_t *za, zip_uint64_t len)
+{
+ zip_cdir_t *cdir, *cdirnew;
+ zip_uint8_t *match;
+ zip_int64_t buf_offset;
+ zip_uint64_t buflen;
+ zip_int64_t a;
+ zip_int64_t best;
+ zip_error_t error;
+ zip_buffer_t *buffer;
+
+ if (len < EOCDLEN) {
+ zip_error_set(&za->error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ buflen = (len < CDBUFSIZE ? len : CDBUFSIZE);
+ if (zip_source_seek(za->src, -(zip_int64_t)buflen, SEEK_END) < 0) {
+ zip_error_t *src_error = zip_source_error(za->src);
+ if (zip_error_code_zip(src_error) != ZIP_ER_SEEK || zip_error_code_system(src_error) != EFBIG) {
+ /* seek before start of file on my machine */
+ _zip_error_copy(&za->error, src_error);
+ return NULL;
+ }
+ }
+ if ((buf_offset = zip_source_tell(za->src)) < 0) {
+ _zip_error_set_from_source(&za->error, za->src);
+ return NULL;
+ }
+
+ if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) {
+ return NULL;
+ }
+
+ best = -1;
+ cdir = NULL;
+ if (buflen >= CDBUFSIZE) {
+ /* EOCD64 locator is before EOCD, so leave place for it */
+ _zip_buffer_set_offset(buffer, EOCD64LOCLEN);
+ }
+ zip_error_set(&error, ZIP_ER_NOZIP, 0);
+
+ 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)));
+ }
+
+ _zip_buffer_free(buffer);
+
+ if (best < 0) {
+ _zip_error_copy(&za->error, &error);
+ _zip_cdir_free(cdir);
+ return NULL;
+ }
+
+ return cdir;
+}
+
+
+static unsigned char *
+_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen)
+{
+ const unsigned char *p;
+
+ if ((biglen < littlelen) || (littlelen == 0))
+ 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)
+ return (unsigned char *)p;
+ }
+
+ return NULL;
+}
+
+
+static zip_cdir_t *
+_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error)
+{
+ zip_cdir_t *cd;
+ zip_uint64_t i, nentry, size, offset, eocd_offset;
+
+ if (_zip_buffer_left(buffer) < EOCDLEN) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+
+ eocd_offset = _zip_buffer_offset(buffer);
+
+ _zip_buffer_get(buffer, 4); /* magic already verified */
+
+ if (_zip_buffer_get_32(buffer) != 0) {
+ zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ return NULL;
+ }
+
+ /* number of cdir-entries on this disk */
+ i = _zip_buffer_get_16(buffer);
+ /* number of cdir-entries */
+ nentry = _zip_buffer_get_16(buffer);
+
+ if (nentry != i) {
+ zip_error_set(error, ZIP_ER_NOZIP, 0);
+ return NULL;
+ }
+
+ size = _zip_buffer_get_32(buffer);
+ offset = _zip_buffer_get_32(buffer);
+
+ if (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 != buf_offset + eocd_offset) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+
+ if ((cd=_zip_cdir_new(nentry, error)) == NULL)
+ return NULL;
+
+ cd->size = size;
+ cd->offset = offset;
+
+ return cd;
+}
+
+
+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_cdir_t *cd;
+ zip_uint64_t offset;
+ zip_uint8_t eocd[EOCD64LEN];
+ zip_uint64_t eocd_offset;
+ zip_uint64_t size, nentry, i, eocdloc_offset;
+ bool free_buffer;
+ zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64;
+
+ eocdloc_offset = _zip_buffer_offset(buffer);
+
+ _zip_buffer_get(buffer, 4); /* magic already verified */
+
+ num_disks = _zip_buffer_get_16(buffer);
+ eocd_disk = _zip_buffer_get_16(buffer);
+ eocd_offset = _zip_buffer_get_64(buffer);
+
+ if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) {
+ zip_error_set(error, ZIP_ER_SEEK, EFBIG);
+ return NULL;
+ }
+
+ if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+
+ 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;
+ }
+ 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 (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ if (free_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return NULL;
+ }
+
+ size = _zip_buffer_get_64(buffer);
+
+ if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ if (free_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return NULL;
+ }
+
+ _zip_buffer_get(buffer, 4); /* skip version made by/needed */
+
+ num_disks64 = _zip_buffer_get_32(buffer);
+ eocd_disk64 = _zip_buffer_get_32(buffer);
+
+ /* if eocd values are 0xffff, we have to use eocd64 values.
+ otherwise, if the values are not the same, it's inconsistent;
+ in any case, if the value is not 0, we don't support it */
+ if (num_disks == 0xffff) {
+ num_disks = num_disks64;
+ }
+ if (eocd_disk == 0xffff) {
+ eocd_disk = eocd_disk64;
+ }
+ if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+ if (num_disks != 0 || eocd_disk != 0) {
+ zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ return NULL;
+ }
+
+ nentry = _zip_buffer_get_64(buffer);
+ i = _zip_buffer_get_64(buffer);
+
+ if (nentry != i) {
+ zip_error_set(error, ZIP_ER_MULTIDISK, 0);
+ if (free_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return NULL;
+ }
+
+ size = _zip_buffer_get_64(buffer);
+ offset = _zip_buffer_get_64(buffer);
+
+ if (!_zip_buffer_ok(buffer)) {
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ if (free_buffer) {
+ _zip_buffer_free(buffer);
+ }
+ return NULL;
+ }
+
+ if (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 ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) {
+ zip_error_set(error, ZIP_ER_INCONS, 0);
+ return NULL;
+ }
+
+ if ((cd=_zip_cdir_new(nentry, error)) == NULL)
+ return NULL;
+
+
+ cd->size = size;
+ cd->offset = offset;
+
+ return cd;
+}
diff --git a/src/Common/libzip/zip_rename.c b/src/Common/libzip/zip_rename.c
new file mode 100644
index 00000000..14e101d7
--- /dev/null
+++ b/src/Common/libzip/zip_rename.c
@@ -0,0 +1,45 @@
+/*
+ zip_rename.c -- rename file in zip archive
+ Copyright (C) 1999-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
+ 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 <string.h>
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+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
new file mode 100644
index 00000000..eed019a0
--- /dev/null
+++ b/src/Common/libzip/zip_replace.c
@@ -0,0 +1,43 @@
+/*
+ zip_replace.c -- replace file via callback function
+ Copyright (C) 1999-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
+ 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.
+*/
+
+
+#define _ZIP_COMPILING_DEPRECATED
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+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
new file mode 100644
index 00000000..9090eec9
--- /dev/null
+++ b/src/Common/libzip/zip_set_archive_comment.c
@@ -0,0 +1,82 @@
+/*
+ zip_set_archive_comment.c -- set archive comment
+ Copyright (C) 2006-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
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len)
+{
+ zip_string_t *cstr;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (len > 0 && comment == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (len > 0) {
+ if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL)
+ return -1;
+
+ if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) {
+ _zip_string_free(cstr);
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+ }
+ else
+ cstr = NULL;
+
+ _zip_string_free(za->comment_changes);
+ za->comment_changes = NULL;
+
+ if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr))
+ || (za->comment_orig == NULL && cstr == NULL))) {
+ _zip_string_free(cstr);
+ za->comment_changed = 0;
+ }
+ else {
+ za->comment_changes = cstr;
+ za->comment_changed = 1;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_set_archive_flag.c b/src/Common/libzip/zip_set_archive_flag.c
new file mode 100644
index 00000000..2625b2e6
--- /dev/null
+++ b/src/Common/libzip/zip_set_archive_flag.c
@@ -0,0 +1,67 @@
+/*
+ zip_get_archive_flag.c -- set archive global flag
+ Copyright (C) 2008-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
+ 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"
+
+
+ZIP_EXTERN int
+zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value)
+{
+ unsigned int new_flags;
+
+ if (value)
+ new_flags = za->ch_flags | flag;
+ else
+ new_flags = za->ch_flags & ~flag;
+
+ if (new_flags == za->ch_flags)
+ return 0;
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if ((flag & ZIP_AFL_RDONLY) && value
+ && (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
+ if (_zip_changed(za, NULL)) {
+ zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return -1;
+ }
+ }
+
+ za->ch_flags = new_flags;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_set_default_password.c b/src/Common/libzip/zip_set_default_password.c
new file mode 100644
index 00000000..10b48062
--- /dev/null
+++ b/src/Common/libzip/zip_set_default_password.c
@@ -0,0 +1,59 @@
+/*
+ zip_set_default_password.c -- set default password for decryption
+ 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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_set_default_password(zip_t *za, const char *passwd)
+{
+ if (za == NULL)
+ return -1;
+
+ free(za->default_password);
+
+ if (passwd) {
+ if ((za->default_password=strdup(passwd)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ }
+ else
+ za->default_password = NULL;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_set_file_comment.c b/src/Common/libzip/zip_set_file_comment.c
new file mode 100644
index 00000000..d3566937
--- /dev/null
+++ b/src/Common/libzip/zip_set_file_comment.c
@@ -0,0 +1,49 @@
+/*
+ zip_set_file_comment.c -- set comment for file in archive
+ Copyright (C) 2006-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
+ 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"
+
+
+ZIP_EXTERN int
+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;
+ }
+ return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0);
+}
diff --git a/src/Common/libzip/zip_set_file_compression.c b/src/Common/libzip/zip_set_file_compression.c
new file mode 100644
index 00000000..7bb0bf94
--- /dev/null
+++ b/src/Common/libzip/zip_set_file_compression.c
@@ -0,0 +1,87 @@
+/*
+ zip_set_file_compression.c -- set compression for file in archive
+ Copyright (C) 2012-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
+ 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"
+
+
+ZIP_EXTERN int
+zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags)
+{
+ zip_entry_t *e;
+ zip_int32_t old_method;
+
+ if (idx >= za->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) {
+ zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+ return -1;
+ }
+
+ 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 */
+
+ if (method == old_method) {
+ if (e->changes) {
+ e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
+ if (e->changes->changed == 0) {
+ _zip_dirent_free(e->changes);
+ e->changes = NULL;
+ }
+ }
+ }
+ 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;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_set_name.c b/src/Common/libzip/zip_set_name.c
new file mode 100644
index 00000000..2a461437
--- /dev/null
+++ b/src/Common/libzip/zip_set_name.c
@@ -0,0 +1,158 @@
+/*
+ zip_set_name.c -- rename helper function
+ 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>
+
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+int
+_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
+{
+ zip_entry_t *e;
+ zip_string_t *str;
+ bool same_as_orig;
+ zip_int64_t i;
+ const zip_uint8_t *old_name, *new_name;
+ zip_string_t *old_str;
+
+ if (idx >= za->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (ZIP_IS_RDONLY(za)) {
+ zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+ return -1;
+ }
+
+ 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)
+ return -1;
+ if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
+ str->encoding = ZIP_ENCODING_UTF8_KNOWN;
+ }
+ else
+ str = NULL;
+
+ /* TODO: encoding flags needed for CP437? */
+ if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
+ _zip_string_free(str);
+ zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
+ }
+
+ /* no effective name change */
+ if (i>=0 && (zip_uint64_t)i == idx) {
+ _zip_string_free(str);
+ return 0;
+ }
+
+ e = za->entry+idx;
+
+ if (e->orig)
+ same_as_orig = _zip_string_equal(e->orig->filename, str);
+ else
+ same_as_orig = false;
+
+ if (!same_as_orig && e->changes == NULL) {
+ if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ _zip_string_free(str);
+ return -1;
+ }
+ }
+
+ if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) {
+ _zip_string_free(str);
+ return -1;
+ }
+
+ if (e->changes) {
+ old_str = e->changes->filename;
+ }
+ else if (e->orig) {
+ old_str = e->orig->filename;
+ }
+ else {
+ old_str = NULL;
+ }
+
+ if (old_str) {
+ if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) {
+ _zip_string_free(str);
+ return -1;
+ }
+ }
+ else {
+ old_name = NULL;
+ }
+
+ if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) {
+ _zip_string_free(str);
+ return -1;
+ }
+ if (old_name) {
+ _zip_hash_delete(za->names, old_name, NULL);
+ }
+
+ if (same_as_orig) {
+ if (e->changes) {
+ if (e->changes->changed & ZIP_DIRENT_FILENAME) {
+ _zip_string_free(e->changes->filename);
+ e->changes->changed &= ~ZIP_DIRENT_FILENAME;
+ if (e->changes->changed == 0) {
+ _zip_dirent_free(e->changes);
+ e->changes = NULL;
+ }
+ else {
+ /* TODO: what if not cloned? can that happen? */
+ e->changes->filename = e->orig->filename;
+ }
+ }
+ }
+ _zip_string_free(str);
+ }
+ else {
+ if (e->changes->changed & ZIP_DIRENT_FILENAME) {
+ _zip_string_free(e->changes->filename);
+ }
+ e->changes->changed |= ZIP_DIRENT_FILENAME;
+ e->changes->filename = str;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_begin_write.c b/src/Common/libzip/zip_source_begin_write.c
new file mode 100644
index 00000000..04593377
--- /dev/null
+++ b/src/Common/libzip/zip_source_begin_write.c
@@ -0,0 +1,53 @@
+/*
+ zip_source_begin_write.c -- start a new file for writing
+ 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
+ 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"
+
+
+ZIP_EXTERN int
+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;
+ }
+
+ if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_BEGIN_WRITE) < 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
new file mode 100644
index 00000000..f3f8ee0d
--- /dev/null
+++ b/src/Common/libzip/zip_source_buffer.c
@@ -0,0 +1,435 @@
+/*
+ zip_source_buffer.c -- create zip data source from buffer
+ 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.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+#ifndef WRITE_FRAGMENT_SIZE
+#define WRITE_FRAGMENT_SIZE 64*1024
+#endif
+
+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;
+};
+
+typedef struct buffer buffer_t;
+
+struct read_data {
+ zip_error_t error;
+ time_t mtime;
+ buffer_t *in;
+ buffer_t *out;
+};
+
+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 zip_int64_t 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);
+static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *);
+
+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)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_buffer_create(data, len, freep, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error)
+{
+ struct read_data *ctx;
+ zip_source_t *zs;
+
+ if (data == NULL && len > 0) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+
+ ctx->out = NULL;
+ ctx->mtime = time(NULL);
+ zip_error_init(&ctx->error);
+
+ if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) {
+ buffer_free(ctx->in);
+ free(ctx);
+ return NULL;
+ }
+
+ return zs;
+}
+
+
+static zip_int64_t
+read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct read_data *ctx = (struct read_data *)state;
+
+ 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_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_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_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;
+ }
+}
+
+
+static void
+buffer_free(buffer_t *buffer)
+{
+ if (buffer == NULL) {
+ return;
+ }
+
+ if (buffer->free_data) {
+ zip_uint64_t i;
+
+ for (i=0; i < buffer->nfragments; i++) {
+ free(buffer->fragments[i]);
+ }
+ }
+ free(buffer->fragments);
+ free(buffer);
+}
+
+
+static buffer_t *
+buffer_new(zip_uint64_t fragment_size)
+{
+ buffer_t *buffer;
+
+ if ((buffer = malloc(sizeof(*buffer))) == NULL) {
+ return NULL;
+ }
+
+ 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;
+
+ return buffer;
+}
+
+
+static buffer_t *
+buffer_new_read(const void *data, zip_uint64_t length, int free_data)
+{
+ buffer_t *buffer;
+
+ if ((buffer = buffer_new(length)) == NULL) {
+ return NULL;
+ }
+
+ buffer->size = length;
+
+ if (length > 0) {
+ if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
+ buffer_free(buffer);
+ return NULL;
+ }
+ buffer->fragments_capacity = 1;
+
+ buffer->nfragments = 1;
+ buffer->fragments[0] = (zip_uint8_t *)data;
+ buffer->free_data = free_data;
+ }
+
+ return buffer;
+}
+
+
+static buffer_t *
+buffer_new_write(zip_uint64_t fragment_size)
+{
+ buffer_t *buffer;
+
+ if ((buffer = buffer_new(fragment_size)) == NULL) {
+ return NULL;
+ }
+
+ if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
+ buffer_free(buffer);
+ return NULL;
+ }
+ buffer->fragments_capacity = 1;
+ buffer->nfragments = 0;
+ buffer->free_data = 1;
+
+ return buffer;
+}
+
+
+static zip_int64_t
+buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length)
+{
+ zip_uint64_t n, i, fragment_offset;
+
+ length = ZIP_MIN(length, buffer->size - buffer->offset);
+
+ if (length == 0) {
+ return 0;
+ }
+ if (length > ZIP_INT64_MAX) {
+ return -1;
+ }
+
+ i = buffer->offset / buffer->fragment_size;
+ fragment_offset = buffer->offset % buffer->fragment_size;
+ 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);
+
+ n += left;
+ i++;
+ fragment_offset = 0;
+ }
+
+ buffer->offset += n;
+ return (zip_int64_t)n;
+}
+
+
+static int
+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;
+ }
+
+ buffer->offset = (zip_uint64_t)new_offset;
+ return 0;
+}
+
+
+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;
+
+ if (buffer->offset + length + buffer->fragment_size - 1 < length) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ /* 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;
+
+ if (needed_fragments > buffer->fragments_capacity) {
+ zip_uint64_t new_capacity = buffer->fragments_capacity;
+
+ while (new_capacity < needed_fragments) {
+ new_capacity *= 2;
+ }
+
+ fragments = realloc(buffer->fragments, new_capacity * sizeof(*fragments));
+
+ if (fragments == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ buffer->fragments = fragments;
+ buffer->fragments_capacity = new_capacity;
+ }
+
+ while (buffer->nfragments < needed_fragments) {
+ if ((buffer->fragments[buffer->nfragments] = malloc(buffer->fragment_size)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+ buffer->nfragments++;
+ }
+ }
+
+ i = buffer->offset / buffer->fragment_size;
+ fragment_offset = buffer->offset % buffer->fragment_size;
+ 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);
+
+ n += left;
+ i++;
+ fragment_offset = 0;
+ }
+
+ buffer->offset += n;
+ if (buffer->offset > buffer->size) {
+ buffer->size = buffer->offset;
+ }
+
+ return (zip_int64_t)n;
+}
diff --git a/src/Common/libzip/zip_source_call.c b/src/Common/libzip/zip_source_call.c
new file mode 100644
index 00000000..21f28bc4
--- /dev/null
+++ b/src/Common/libzip/zip_source_call.c
@@ -0,0 +1,69 @@
+/*
+ zip_source_call.c -- invoke callback command on zip_source
+ 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
+ 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"
+
+
+zip_int64_t
+_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;
+ }
+
+ if (src->src == NULL) {
+ ret = src->cb.f(src->ud, data, length, command);
+ }
+ else {
+ 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]);
+ }
+ }
+ }
+
+ return ret;
+}
diff --git a/src/Common/libzip/zip_source_close.c b/src/Common/libzip/zip_source_close.c
new file mode 100644
index 00000000..36bc8423
--- /dev/null
+++ b/src/Common/libzip/zip_source_close.c
@@ -0,0 +1,58 @@
+/*
+ zip_source_close.c -- close zip_source (stop reading)
+ 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
+ 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"
+
+
+int
+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;
+ }
+
+ src->open_count--;
+ if (src->open_count == 0) {
+ _zip_source_call(src, NULL, 0, ZIP_SOURCE_CLOSE);
+
+ if (ZIP_SOURCE_IS_LAYERED(src)) {
+ if (zip_source_close(src->src) < 0) {
+ zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_commit_write.c b/src/Common/libzip/zip_source_commit_write.c
new file mode 100644
index 00000000..ba77abc3
--- /dev/null
+++ b/src/Common/libzip/zip_source_commit_write.c
@@ -0,0 +1,64 @@
+/*
+ zip_source_commit_write.c -- commit changes to file
+ 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
+ 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"
+
+
+ZIP_EXTERN int
+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;
+ }
+
+ if (src->open_count > 1) {
+ zip_error_set(&src->error, ZIP_ER_INUSE, 0);
+ return -1;
+ }
+ else if (ZIP_SOURCE_IS_OPEN_READING(src)) {
+ if (zip_source_close(src) < 0) {
+ return -1;
+ }
+ }
+
+ 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_CLOSED;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_crc.c b/src/Common/libzip/zip_source_crc.c
new file mode 100644
index 00000000..01f526c6
--- /dev/null
+++ b/src/Common/libzip/zip_source_crc.c
@@ -0,0 +1,202 @@
+/*
+ zip_source_crc.c -- pass-through source that calculates CRC32 and size
+ Copyright (C) 2009-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.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "zipint.h"
+
+struct crc_context {
+ int validate; /* whether to check CRC on EOF and return error on mismatch */
+ int crc_complete; /* whether CRC was computed for complete file */
+ zip_error_t error;
+ zip_uint64_t size;
+ zip_uint64_t position; /* current reading position */
+ zip_uint64_t crc_position; /* how far we've computed the CRC */
+ zip_uint32_t crc;
+};
+
+static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
+
+
+zip_source_t *
+zip_source_crc(zip_t *za, zip_source_t *src, int validate)
+{
+ struct crc_context *ctx;
+
+ if (src == NULL) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ zip_error_init(&ctx->error);
+ ctx->validate = validate;
+ ctx->crc_complete = 0;
+ ctx->crc_position = 0;
+ ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
+ ctx->size = 0;
+
+ return zip_source_layered(za, src, crc_read, ctx);
+}
+
+
+static zip_int64_t
+crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct crc_context *ctx;
+ zip_int64_t n;
+
+ ctx = (struct crc_context *)_ctx;
+
+ 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;
+ }
+ }
+ 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;
+ }
+ 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_deflate.c b/src/Common/libzip/zip_source_deflate.c
new file mode 100644
index 00000000..2574ad01
--- /dev/null
+++ b/src/Common/libzip/zip_source_deflate.c
@@ -0,0 +1,415 @@
+/*
+ zip_source_deflate.c -- deflate (de)compressoin routines
+ Copyright (C) 2009-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>
+
+ 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>
+#include <string.h>
+#include <limits.h>
+
+#include "zipint.h"
+
+struct deflate {
+ zip_error_t error;
+
+ bool eof;
+ bool can_store;
+ bool is_stored;
+ int mem_level;
+ zip_uint64_t size;
+ zip_uint8_t buffer[BUFSIZE];
+ z_stream zstr;
+};
+
+static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
+static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
+static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
+static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
+static void deflate_free(struct deflate *);
+
+
+zip_source_t *
+zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
+{
+ struct deflate *ctx;
+ zip_source_t *s2;
+
+ if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ zip_error_init(&ctx->error);
+ ctx->eof = false;
+ ctx->is_stored = false;
+ ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
+ if (flags & ZIP_CODEC_ENCODE) {
+ ctx->mem_level = MAX_MEM_LEVEL;
+ }
+
+ if ((s2=zip_source_layered(za, src,
+ ((flags & ZIP_CODEC_ENCODE)
+ ? deflate_compress : deflate_decompress),
+ ctx)) == NULL) {
+ deflate_free(ctx);
+ return NULL;
+ }
+
+ return s2;
+}
+
+
+static zip_int64_t
+compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
+{
+ int end, ret;
+ zip_int64_t n;
+ zip_uint64_t out_offset;
+ uInt out_len;
+
+ if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
+ return -1;
+
+ if (len == 0 || ctx->is_stored) {
+ return 0;
+ }
+
+ out_offset = 0;
+ out_len = (uInt)ZIP_MIN(UINT_MAX, len);
+ ctx->zstr.next_out = (Bytef *)data;
+ ctx->zstr.avail_out = out_len;
+
+ end = 0;
+ while (!end) {
+ ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
+
+ switch (ret) {
+ case Z_STREAM_END:
+ if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
+ ctx->is_stored = true;
+ ctx->size = ctx->zstr.total_in;
+ memcpy(data, ctx->buffer, ctx->size);
+ return (zip_int64_t)ctx->size;
+ }
+ /* fallthrough */
+ case Z_OK:
+ /* all ok */
+
+ if (ctx->zstr.avail_out == 0) {
+ out_offset += out_len;
+ if (out_offset < len) {
+ out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
+ ctx->zstr.next_out = (Bytef *)data+out_offset;
+ ctx->zstr.avail_out = out_len;
+ }
+ else {
+ ctx->can_store = false;
+ end = 1;
+ }
+ }
+ else if (ctx->eof && ctx->zstr.avail_in == 0)
+ end = 1;
+ break;
+
+ case Z_BUF_ERROR:
+ if (ctx->zstr.avail_in == 0) {
+ if (ctx->eof) {
+ end = 1;
+ break;
+ }
+
+ if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
+ _zip_error_set_from_source(&ctx->error, src);
+ end = 1;
+ break;
+ }
+ else if (n == 0) {
+ ctx->eof = true;
+ /* TODO: check against stat of src? */
+ ctx->size = ctx->zstr.total_in;
+ }
+ else {
+ if (ctx->zstr.total_in > 0) {
+ /* we overwrote a previously filled ctx->buffer */
+ ctx->can_store = false;
+ }
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = (uInt)n;
+ }
+ continue;
+ }
+ /* fallthrough */
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_STREAM_ERROR:
+ case Z_MEM_ERROR:
+ zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
+
+ end = 1;
+ break;
+ }
+ }
+
+ if (ctx->zstr.avail_out < len) {
+ ctx->can_store = false;
+ return (zip_int64_t)(len - ctx->zstr.avail_out);
+ }
+
+ return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
+}
+
+
+static zip_int64_t
+decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
+{
+ int end, ret;
+ zip_int64_t n;
+ zip_uint64_t out_offset;
+ uInt out_len;
+
+ if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
+ return -1;
+
+ if (len == 0)
+ return 0;
+
+ out_offset = 0;
+ out_len = (uInt)ZIP_MIN(UINT_MAX, len);
+ ctx->zstr.next_out = (Bytef *)data;
+ ctx->zstr.avail_out = out_len;
+
+ end = 0;
+ while (!end) {
+ ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
+
+ switch (ret) {
+ case Z_OK:
+ if (ctx->zstr.avail_out == 0) {
+ out_offset += out_len;
+ if (out_offset < len) {
+ out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
+ ctx->zstr.next_out = (Bytef *)data+out_offset;
+ ctx->zstr.avail_out = out_len;
+ }
+ else {
+ end = 1;
+ }
+ }
+ break;
+
+ case Z_STREAM_END:
+ ctx->eof = 1;
+ end = 1;
+ break;
+
+ case Z_BUF_ERROR:
+ if (ctx->zstr.avail_in == 0) {
+ if (ctx->eof) {
+ end = 1;
+ break;
+ }
+
+ if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
+ _zip_error_set_from_source(&ctx->error, src);
+ end = 1;
+ break;
+ }
+ else if (n == 0) {
+ ctx->eof = 1;
+ }
+ else {
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = (uInt)n;
+ }
+ continue;
+ }
+ /* fallthrough */
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_STREAM_ERROR:
+ case Z_MEM_ERROR:
+ zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
+ end = 1;
+ break;
+ }
+ }
+
+ if (ctx->zstr.avail_out < len)
+ return (zip_int64_t)(len - ctx->zstr.avail_out);
+
+ return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
+}
+
+
+static zip_int64_t
+deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct deflate *ctx;
+ int ret;
+
+ ctx = (struct deflate *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ ctx->zstr.zalloc = Z_NULL;
+ ctx->zstr.zfree = Z_NULL;
+ ctx->zstr.opaque = NULL;
+ ctx->zstr.avail_in = 0;
+ ctx->zstr.next_in = NULL;
+ ctx->zstr.avail_out = 0;
+ ctx->zstr.next_out = NULL;
+
+ /* negative value to tell zlib not to write a header */
+ if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
+ zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
+ return -1;
+ }
+
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ return compress_read(src, ctx, data, len);
+
+ case ZIP_SOURCE_CLOSE:
+ deflateEnd(&ctx->zstr);
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ zip_stat_t *st;
+
+ st = (zip_stat_t *)data;
+
+ st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
+ st->valid |= ZIP_STAT_COMP_METHOD;
+ if (ctx->eof) {
+ st->comp_size = ctx->size;
+ st->valid |= ZIP_STAT_COMP_SIZE;
+ }
+ else
+ st->valid &= ~ZIP_STAT_COMP_SIZE;
+ }
+ return 0;
+
+ case ZIP_SOURCE_ERROR:
+ return zip_error_to_data(&ctx->error, data, len);
+
+ case ZIP_SOURCE_FREE:
+ deflate_free(ctx);
+ return 0;
+
+ case ZIP_SOURCE_SUPPORTS:
+ return ZIP_SOURCE_SUPPORTS_READABLE;
+
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
+ return -1;
+ }
+}
+
+
+static zip_int64_t
+deflate_decompress(zip_source_t *src, void *ud, void *data,
+ zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct deflate *ctx;
+ zip_int64_t n;
+ int ret;
+
+ ctx = (struct deflate *)ud;
+
+ switch (cmd) {
+ case ZIP_SOURCE_OPEN:
+ if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
+ _zip_error_set_from_source(&ctx->error, src);
+ return -1;
+ }
+
+ ctx->zstr.zalloc = Z_NULL;
+ ctx->zstr.zfree = Z_NULL;
+ ctx->zstr.opaque = NULL;
+ ctx->zstr.next_in = (Bytef *)ctx->buffer;
+ ctx->zstr.avail_in = (uInt)n;
+
+ /* negative value to tell zlib that there is no header */
+ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
+ zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
+ return -1;
+ }
+ return 0;
+
+ case ZIP_SOURCE_READ:
+ return decompress_read(src, ctx, data, len);
+
+ case ZIP_SOURCE_CLOSE:
+ inflateEnd(&ctx->zstr);
+ return 0;
+
+ case ZIP_SOURCE_STAT:
+ {
+ zip_stat_t *st;
+
+ st = (zip_stat_t *)data;
+
+ st->comp_method = ZIP_CM_STORE;
+ if (st->comp_size > 0 && st->size > 0)
+ st->comp_size = st->size;
+
+ 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:
+ 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);
+
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
+ return -1;
+ }
+}
+
+
+static void
+deflate_free(struct deflate *ctx)
+{
+ free(ctx);
+}
diff --git a/src/Common/libzip/zip_source_error.c b/src/Common/libzip/zip_source_error.c
new file mode 100644
index 00000000..e09199bb
--- /dev/null
+++ b/src/Common/libzip/zip_source_error.c
@@ -0,0 +1,42 @@
+/*
+ zip_source_error.c -- get last error from zip_source
+ 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
+ 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"
+
+
+zip_error_t *
+zip_source_error(zip_source_t *src)
+{
+ return &src->error;
+}
diff --git a/src/Common/libzip/zip_source_file.c b/src/Common/libzip/zip_source_file.c
new file mode 100644
index 00000000..8678c1a0
--- /dev/null
+++ b/src/Common/libzip/zip_source_file.c
@@ -0,0 +1,63 @@
+/*
+ zip_source_file.c -- create data source from file
+ 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>
+
+ 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 <stdio.h>
+
+#include "zipint.h"
+
+#ifdef _WIN32
+#error This file is incompatible with Windows, use zip_source_win32utf8.c instead.
+#error Something probably went wrong with configure/cmake.
+#endif
+
+ZIP_EXTERN zip_source_t *
+zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_file_create(fname, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
+{
+ if (fname == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_file_or_p(fname, NULL, start, length, NULL, error);
+}
diff --git a/src/Common/libzip/zip_source_filep.c b/src/Common/libzip/zip_source_filep.c
new file mode 100644
index 00000000..70255dec
--- /dev/null
+++ b/src/Common/libzip/zip_source_filep.c
@@ -0,0 +1,503 @@
+/*
+ zip_source_filep.c -- create data source from FILE *
+ 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>
+
+ 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 <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+/* WIN32 needs <fcntl.h> for _O_BINARY */
+#include <fcntl.h>
+#endif
+
+/* Windows sys/types.h does not provide these */
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO)
+#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO)
+#elif defined(_S_IWRITE)
+#define _SAFE_MASK (_S_IWRITE)
+#else
+#error do not know safe values for umask, please report this
+#endif
+
+#ifdef _MSC_VER
+/* MSVC doesn't have mode_t */
+typedef int mode_t;
+#endif
+
+struct read_file {
+ zip_error_t error; /* last error information */
+ zip_int64_t supports;
+
+ /* reading */
+ char *fname; /* name of file to read from */
+ FILE *f; /* file to read from */
+ 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 */
+ char *tmpname;
+ FILE *fout;
+};
+
+static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
+static int create_temp_output(struct read_file *ctx);
+static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error);
+static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error);
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_filep_create(file, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
+{
+ if (file == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_file_or_p(NULL, file, start, length, NULL, error);
+}
+
+
+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)
+{
+ struct read_file *ctx;
+ zip_source_t *zs;
+
+ if (file == NULL && fname == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->fname = NULL;
+ if (fname) {
+ if ((ctx->fname=strdup(fname)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+ }
+ ctx->f = file;
+ ctx->start = start;
+ ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len);
+ if (st) {
+ memcpy(&ctx->st, st, sizeof(ctx->st));
+ ctx->st.name = NULL;
+ ctx->st.valid &= ~ZIP_STAT_NAME;
+ }
+ else {
+ zip_stat_init(&ctx->st);
+ }
+
+ ctx->tmpname = NULL;
+ ctx->fout = NULL;
+
+ zip_error_init(&ctx->error);
+
+ ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
+ if (ctx->fname) {
+ struct stat sb;
+
+ if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+ }
+ }
+ else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
+ }
+
+ if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) {
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+
+ return zs;
+}
+
+
+static int
+create_temp_output(struct read_file *ctx)
+{
+ char *temp;
+ int tfd;
+ mode_t mask;
+ FILE *tfp;
+
+ 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);
+
+ mask = umask(_SAFE_MASK);
+ if ((tfd=mkstemp(temp)) == -1) {
+ zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
+ umask(mask);
+ free(temp);
+ return -1;
+ }
+ umask(mask);
+
+ if ((tfp=fdopen(tfd, "r+b")) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
+ close(tfd);
+ (void)remove(temp);
+ free(temp);
+ return -1;
+ }
+
+#ifdef _WIN32
+ /*
+ According to Pierre Joye, Windows in some environments per
+ default creates text files, so force binary mode.
+ */
+ _setmode(_fileno(tfp), _O_BINARY );
+#endif
+
+ ctx->fout = tfp;
+ ctx->tmpname = temp;
+
+ return 0;
+}
+
+
+static zip_int64_t
+read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct read_file *ctx;
+ char *buf;
+ zip_uint64_t n;
+ size_t i;
+
+ ctx = (struct read_file *)state;
+ buf = (char *)data;
+
+ 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_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) {
+ return -1;
+ }
+ }
+ ctx->current = ctx->start;
+ 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)
+ 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;
+ }
+ 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 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
+ 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, 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))
+ return -1;
+
+ if (ctx->st.valid != 0)
+ memcpy(data, &ctx->st, sizeof(ctx->st));
+ else {
+ zip_stat_t *st;
+ struct stat fst;
+ int err;
+
+ if (ctx->f)
+ err = fstat(fileno(ctx->f), &fst);
+ else
+ err = stat(ctx->fname, &fst);
+
+ if (err != 0) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, errno);
+ return -1;
+ }
+
+ st = (zip_stat_t *)data;
+
+ zip_stat_init(st);
+ st->mtime = fst.st_mtime;
+ st->valid |= ZIP_STAT_MTIME;
+ if (ctx->end != 0) {
+ st->size = ctx->end - ctx->start;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+ else if ((fst.st_mode&S_IFMT) == S_IFREG) {
+ st->size = (zip_uint64_t)fst.st_size;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+ }
+ return sizeof(ctx->st);
+ }
+
+ case ZIP_SOURCE_SUPPORTS:
+ return ctx->supports;
+
+ case ZIP_SOURCE_TELL:
+ return (zip_int64_t)ctx->current;
+
+ case ZIP_SOURCE_TELL_WRITE:
+ {
+ off_t ret = ftello(ctx->fout);
+
+ 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;
+ }
+}
+
+
+static int
+_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error)
+{
+ if (offset > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
+ return -1;
+ }
+ return _zip_fseek(f, (zip_int64_t)offset, whence, error);
+}
+
+
+static int
+_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error)
+{
+ if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
+ zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
+ return -1;
+ }
+ if (fseeko(f, (off_t)offset, whence) < 0) {
+ zip_error_set(error, ZIP_ER_SEEK, errno);
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_free.c b/src/Common/libzip/zip_source_free.c
new file mode 100644
index 00000000..90704699
--- /dev/null
+++ b/src/Common/libzip/zip_source_free.c
@@ -0,0 +1,72 @@
+/*
+ zip_source_free.c -- free zip data source
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN void
+zip_source_free(zip_source_t *src)
+{
+ if (src == NULL)
+ return;
+
+ if (src->refcount > 0) {
+ src->refcount--;
+ }
+ if (src->refcount > 0) {
+ return;
+ }
+
+ if (ZIP_SOURCE_IS_OPEN_READING(src)) {
+ src->open_count = 1; /* force close */
+ zip_source_close(src);
+ }
+ if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
+ zip_source_rollback_write(src);
+ }
+
+ if (src->source_archive && !src->source_closed) {
+ _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);
+ }
+
+ free(src);
+}
diff --git a/src/Common/libzip/zip_source_function.c b/src/Common/libzip/zip_source_function.c
new file mode 100644
index 00000000..1d4be93c
--- /dev/null
+++ b/src/Common/libzip/zip_source_function.c
@@ -0,0 +1,99 @@
+/*
+ zip_source_function.c -- create zip data source from callback function
+ Copyright (C) 1999-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
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_function(zip_t *za, zip_source_callback zcb, void *ud)
+{
+ if (za == NULL) {
+ return NULL;
+ }
+
+ return zip_source_function_create(zcb, ud, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+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)
+ return NULL;
+
+ zs->cb.f = zcb;
+ zs->ud = ud;
+
+ zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
+ if (zs->supports < 0) {
+ zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
+ }
+
+ return zs;
+}
+
+
+ZIP_EXTERN void
+zip_source_keep(zip_source_t *src)
+{
+ src->refcount++;
+}
+
+
+zip_source_t *
+_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);
+ return NULL;
+ }
+
+ src->src = NULL;
+ src->cb.f = NULL;
+ src->ud = NULL;
+ src->open_count = 0;
+ src->write_state = ZIP_SOURCE_WRITE_CLOSED;
+ src->source_closed = false;
+ src->source_archive = NULL;
+ src->refcount = 1;
+ zip_error_init(&src->error);
+
+ return src;
+}
diff --git a/src/Common/libzip/zip_source_is_deleted.c b/src/Common/libzip/zip_source_is_deleted.c
new file mode 100644
index 00000000..e50cdd9e
--- /dev/null
+++ b/src/Common/libzip/zip_source_is_deleted.c
@@ -0,0 +1,42 @@
+/*
+ zip_source_is_deleted.c -- was archive was removed?
+ 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
+ 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"
+
+
+ZIP_EXTERN int
+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
new file mode 100644
index 00000000..94b33101
--- /dev/null
+++ b/src/Common/libzip/zip_source_layered.c
@@ -0,0 +1,69 @@
+/*
+ zip_source_layered.c -- create layered source
+ 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
+ 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>
+
+#include "zipint.h"
+
+
+zip_source_t *
+zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_layered_create(src, cb, ud, &za->error);
+}
+
+
+zip_source_t *
+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;
+
+ zip_source_keep(src);
+ zs->src = src;
+ zs->cb.l = cb;
+ zs->ud = ud;
+
+ zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
+ if (zs->supports < 0) {
+ zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
+ }
+
+ return zs;
+}
diff --git a/src/Common/libzip/zip_source_open.c b/src/Common/libzip/zip_source_open.c
new file mode 100644
index 00000000..ec5e39d5
--- /dev/null
+++ b/src/Common/libzip/zip_source_open.c
@@ -0,0 +1,73 @@
+/*
+ zip_source_open.c -- open zip_source (prepare for reading)
+ 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
+ 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"
+
+ZIP_EXTERN int
+zip_source_open(zip_source_t *src)
+{
+ if (src->source_closed) {
+ return -1;
+ }
+ if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
+ zip_error_set(&src->error, ZIP_ER_DELETED, 0);
+ return -1;
+ }
+
+ if (ZIP_SOURCE_IS_OPEN_READING(src)) {
+ if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) {
+ zip_error_set(&src->error, ZIP_ER_INUSE, 0);
+ return -1;
+ }
+ }
+ else {
+ if (ZIP_SOURCE_IS_LAYERED(src)) {
+ if (zip_source_open(src->src) < 0) {
+ _zip_error_set_from_source(&src->error, src->src);
+ return -1;
+ }
+ }
+
+ if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
+ if (ZIP_SOURCE_IS_LAYERED(src)) {
+ zip_source_close(src->src);
+ }
+ return -1;
+ }
+ }
+
+ src->open_count++;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_pkware.c b/src/Common/libzip/zip_source_pkware.c
new file mode 100644
index 00000000..125e4e2c
--- /dev/null
+++ b/src/Common/libzip/zip_source_pkware.c
@@ -0,0 +1,226 @@
+/*
+ zip_source_pkware.c -- Traditional PKWARE de/encryption routines
+ Copyright (C) 2009-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>
+
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+struct trad_pkware {
+ zip_error_t error;
+ zip_uint32_t key[3];
+};
+
+#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 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 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)
+{
+ struct trad_pkware *ctx;
+ zip_source_t *s2;
+
+ if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ if (flags & ZIP_CODEC_ENCODE) {
+ zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+ return NULL;
+ }
+
+ if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ zip_error_init(&ctx->error);
+
+ ctx->key[0] = KEY0;
+ ctx->key[1] = KEY1;
+ ctx->key[2] = KEY2;
+ decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
+
+ if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
+ pkware_free(ctx);
+ return NULL;
+ }
+
+ return s2;
+}
+
+
+static void
+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;
+ zip_uint64_t i;
+ Bytef b;
+
+ for (i=0; i<len; i++) {
+ b = in[i];
+
+ if (!update_only) {
+ /* decrypt next byte */
+ tmp = (zip_uint16_t)(ctx->key[2] | 2);
+ tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
+ b ^= (Bytef)tmp;
+ }
+
+ /* store cleartext */
+ if (out)
+ out[i] = b;
+
+ /* update keys */
+ ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
+ ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
+ b = (Bytef)(ctx->key[1] >> 24);
+ ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
+ }
+}
+
+
+static int
+decrypt_header(zip_source_t *src, struct trad_pkware *ctx)
+{
+ zip_uint8_t header[HEADERLEN];
+ struct zip_stat st;
+ zip_int64_t n;
+ unsigned short dostime, dosdate;
+
+ 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);
+ return -1;
+ }
+
+ decrypt(ctx, header, header, HEADERLEN, 0);
+
+ if (zip_source_stat(src, &st) < 0) {
+ /* stat failed, skip password validation */
+ return 0;
+ }
+
+ _zip_u2d_time(st.mtime, &dostime, &dosdate);
+
+ if (header[HEADERLEN-1] != st.crc>>24 && header[HEADERLEN-1] != dostime>>8) {
+ zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static zip_int64_t
+pkware_decrypt(zip_source_t *src, void *ud, void *data,
+ zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct trad_pkware *ctx;
+ zip_int64_t n;
+
+ ctx = (struct trad_pkware *)ud;
+
+ 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;
+ }
+}
+
+
+static void
+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
new file mode 100644
index 00000000..061a6f91
--- /dev/null
+++ b/src/Common/libzip/zip_source_read.c
@@ -0,0 +1,50 @@
+/*
+ zip_source_read.c -- read data from zip_source
+ 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
+ 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"
+
+
+zip_int64_t
+zip_source_read(zip_source_t *src, void *data, zip_uint64_t len)
+{
+ if (src->source_closed) {
+ 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);
+ return -1;
+ }
+
+ return _zip_source_call(src, data, len, ZIP_SOURCE_READ);
+}
diff --git a/src/Common/libzip/zip_source_remove.c b/src/Common/libzip/zip_source_remove.c
new file mode 100644
index 00000000..470a5eda
--- /dev/null
+++ b/src/Common/libzip/zip_source_remove.c
@@ -0,0 +1,61 @@
+/*
+ zip_source_remove.c -- remove empty archive
+ 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
+ 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"
+
+
+int
+zip_source_remove(zip_source_t *src)
+{
+ if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
+ return 0;
+ }
+
+ if (ZIP_SOURCE_IS_OPEN_READING(src)) {
+ if (zip_source_close(src) < 0) {
+ return -1;
+ }
+ }
+ if (src->write_state != ZIP_SOURCE_WRITE_CLOSED) {
+ zip_source_rollback_write(src);
+ }
+
+ if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_REMOVE) < 0) {
+ 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
new file mode 100644
index 00000000..c35f30f9
--- /dev/null
+++ b/src/Common/libzip/zip_source_rollback_write.c
@@ -0,0 +1,47 @@
+/*
+ zip_source_rollback_write.c -- discard changes
+ 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
+ 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"
+
+
+ZIP_EXTERN void
+zip_source_rollback_write(zip_source_t *src)
+{
+ if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) {
+ return;
+ }
+
+ _zip_source_call(src, NULL, 0, ZIP_SOURCE_ROLLBACK_WRITE);
+ src->write_state = ZIP_SOURCE_WRITE_CLOSED;
+}
diff --git a/src/Common/libzip/zip_source_seek.c b/src/Common/libzip/zip_source_seek.c
new file mode 100644
index 00000000..c3f47036
--- /dev/null
+++ b/src/Common/libzip/zip_source_seek.c
@@ -0,0 +1,92 @@
+/*
+ zip_source_seek.c -- seek to offset
+ 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
+ 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"
+
+
+ZIP_EXTERN int
+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;
+ }
+ 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;
+ }
+
+ args.offset = offset;
+ args.whence = whence;
+
+ return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0);
+}
+
+
+zip_int64_t
+zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error)
+{
+ zip_int64_t new_offset;
+ zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error);
+
+ if (args == NULL) {
+ return -1;
+ }
+
+ switch (args->whence) {
+ case SEEK_CUR:
+ new_offset = (zip_int64_t)offset + args->offset;
+ break;
+
+ case SEEK_END:
+ new_offset = (zip_int64_t)length + args->offset;
+ break;
+
+ case SEEK_SET:
+ new_offset = args->offset;
+ break;
+
+ default:
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (new_offset < 0 || (zip_uint64_t)new_offset > length) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ return new_offset;
+}
diff --git a/src/Common/libzip/zip_source_seek_write.c b/src/Common/libzip/zip_source_seek_write.c
new file mode 100644
index 00000000..66607664
--- /dev/null
+++ b/src/Common/libzip/zip_source_seek_write.c
@@ -0,0 +1,52 @@
+/*
+ zip_source_seek_write.c -- seek to offset for writing
+ 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
+ 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"
+
+
+ZIP_EXTERN int
+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;
+ }
+
+ 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
new file mode 100644
index 00000000..a6b46d06
--- /dev/null
+++ b/src/Common/libzip/zip_source_stat.c
@@ -0,0 +1,63 @@
+/*
+ zip_source_stat.c -- get meta information from zip_source
+ Copyright (C) 2009-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>
+
+ 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"
+
+
+ZIP_EXTERN int
+zip_source_stat(zip_source_t *src, zip_stat_t *st)
+{
+ if (src->source_closed) {
+ return -1;
+ }
+ if (st == NULL) {
+ zip_error_set(&src->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ 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_call(src, st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_supports.c b/src/Common/libzip/zip_source_supports.c
new file mode 100644
index 00000000..75a4a462
--- /dev/null
+++ b/src/Common/libzip/zip_source_supports.c
@@ -0,0 +1,68 @@
+/*
+ zip_source_supports.c -- check for supported functions
+ Copyright (C) 2014-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>
+
+ 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 <stdarg.h>
+
+#include "zipint.h"
+
+
+zip_int64_t
+zip_source_supports(zip_source_t *src)
+{
+ return src->supports;
+}
+
+
+ZIP_EXTERN zip_int64_t
+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);
+ }
+ va_end(ap);
+
+ return bitmap;
+}
diff --git a/src/Common/libzip/zip_source_tell.c b/src/Common/libzip/zip_source_tell.c
new file mode 100644
index 00000000..f1c10b5b
--- /dev/null
+++ b/src/Common/libzip/zip_source_tell.c
@@ -0,0 +1,50 @@
+/*
+ zip_source_tell.c -- report current offset
+ 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
+ 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"
+
+
+ZIP_EXTERN zip_int64_t
+zip_source_tell(zip_source_t *src)
+{
+ if (src->source_closed) {
+ return -1;
+ }
+ if (!ZIP_SOURCE_IS_OPEN_READING(src)) {
+ 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
new file mode 100644
index 00000000..2fa15072
--- /dev/null
+++ b/src/Common/libzip/zip_source_tell_write.c
@@ -0,0 +1,47 @@
+/*
+ zip_source_tell_write.c -- report current offset for writing
+ 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
+ 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"
+
+
+ZIP_EXTERN zip_int64_t
+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;
+ }
+
+ 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
new file mode 100644
index 00000000..85493b66
--- /dev/null
+++ b/src/Common/libzip/zip_source_win32a.c
@@ -0,0 +1,124 @@
+/*
+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.
+*/
+
+
+#include <stdio.h>
+
+#include "zipint.h"
+#include "zipwin32.h"
+
+static void * _win32_strdup_a(const void *str);
+static HANDLE _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);
+static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
+static int _win32_remove_a(const void *fname);
+
+static _zip_source_win32_file_ops_t win32_ops_a = {
+ _win32_strdup_a,
+ _win32_open_a,
+ _win32_create_temp_a,
+ _win32_rename_temp_a,
+ _win32_remove_a
+};
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_win32a_create(fname, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
+{
+ if (fname == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error);
+}
+
+
+static void *
+_win32_strdup_a(const void *str)
+{
+ return strdup((const char *)str);
+}
+
+
+static HANDLE
+_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);
+}
+
+
+static HANDLE
+_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
+{
+ int len;
+
+ len = strlen((const char *)ctx->fname) + 10;
+ if (*temp == NULL) {
+ if ((*temp = malloc(sizeof(char) * len)) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+ return INVALID_HANDLE_VALUE;
+ }
+ }
+ if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+}
+
+
+static int
+_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx)
+{
+ if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
+ return -1;
+ return 0;
+}
+
+
+static int
+_win32_remove_a(const void *fname)
+{
+ DeleteFileA((const char *)fname);
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_win32handle.c b/src/Common/libzip/zip_source_win32handle.c
new file mode 100644
index 00000000..35e2e679
--- /dev/null
+++ b/src/Common/libzip/zip_source_win32handle.c
@@ -0,0 +1,607 @@
+/*
+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.
+*/
+
+
+#include <wchar.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+#include "zipwin32.h"
+
+static zip_int64_t _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);
+static int _zip_filetime_to_time_t(FILETIME ft, time_t *t);
+static int _zip_seek_win32_u(void *h, zip_uint64_t offset, int whence, zip_error_t *error);
+static int _zip_seek_win32(void *h, zip_int64_t offset, int whence, zip_error_t *error);
+static int _zip_win32_error_to_errno(unsigned long win32err);
+static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx);
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_win32handle_create(h, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+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) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_win32_handle_or_name(NULL, h, start, length, 1, NULL, NULL, error);
+}
+
+
+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_read_file_t *ctx;
+ zip_source_t *zs;
+
+ if (h == INVALID_HANDLE_VALUE && fname == NULL) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ ctx->fname = NULL;
+ if (fname) {
+ if ((ctx->fname = ops->op_strdup(fname)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ free(ctx);
+ return NULL;
+ }
+ }
+
+ ctx->ops = ops;
+ ctx->h = h;
+ ctx->start = start;
+ ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len);
+ ctx->closep = ctx->fname ? 1 : closep;
+ if (st) {
+ memcpy(&ctx->st, st, sizeof(ctx->st));
+ ctx->st.name = NULL;
+ ctx->st.valid &= ~ZIP_STAT_NAME;
+ }
+ else {
+ zip_stat_init(&ctx->st);
+ }
+
+ ctx->tmpname = NULL;
+ ctx->hout = INVALID_HANDLE_VALUE;
+
+ zip_error_init(&ctx->error);
+
+ ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
+ if (ctx->fname) {
+ HANDLE th;
+
+ th = ops->op_open(ctx);
+ if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
+ }
+ if (th != INVALID_HANDLE_VALUE) {
+ CloseHandle(th);
+ }
+ }
+ else if (GetFileType(ctx->h) == FILE_TYPE_DISK) {
+ ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
+ }
+
+ if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
+ free(ctx->fname);
+ free(ctx);
+ return NULL;
+ }
+
+ return zs;
+}
+
+
+static zip_int64_t
+_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ _zip_source_win32_read_file_t *ctx;
+ char *buf;
+ zip_uint64_t n;
+ DWORD i;
+
+ ctx = (_zip_source_win32_read_file_t *)state;
+ buf = (char *)data;
+
+ switch (cmd) {
+ case ZIP_SOURCE_BEGIN_WRITE:
+ if (ctx->fname == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
+ return -1;
+ }
+ return _win32_create_temp_file(ctx);
+
+ case ZIP_SOURCE_COMMIT_WRITE: {
+ if (!CloseHandle(ctx->hout)) {
+ ctx->hout = INVALID_HANDLE_VALUE;
+ zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
+ }
+ ctx->hout = INVALID_HANDLE_VALUE;
+ if (ctx->ops->op_rename_temp(ctx) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ free(ctx->tmpname);
+ ctx->tmpname = NULL;
+ return 0;
+ }
+
+ case ZIP_SOURCE_CLOSE:
+ if (ctx->fname) {
+ CloseHandle(ctx->h);
+ ctx->h = INVALID_HANDLE_VALUE;
+ }
+ 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->closep && ctx->h != INVALID_HANDLE_VALUE)
+ CloseHandle(ctx->h);
+ free(ctx);
+ return 0;
+
+ case ZIP_SOURCE_OPEN:
+ if (ctx->fname) {
+ if ((ctx->h = ctx->ops->op_open(ctx)) == INVALID_HANDLE_VALUE) {
+ zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ }
+
+ if (ctx->closep && ctx->start > 0) {
+ if (_zip_seek_win32_u(ctx->h, ctx->start, SEEK_SET, &ctx->error) < 0) {
+ return -1;
+ }
+ }
+ ctx->current = ctx->start;
+ 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 (!ctx->closep) {
+ if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
+ return -1;
+ }
+ }
+
+ if (!ReadFile(ctx->h, buf, (DWORD)n, &i, NULL)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ ctx->current += i;
+
+ return (zip_int64_t)i;
+
+ case ZIP_SOURCE_REMOVE:
+ if (ctx->ops->op_remove(ctx->fname) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ return 0;
+
+ case ZIP_SOURCE_ROLLBACK_WRITE:
+ if (ctx->hout) {
+ CloseHandle(ctx->hout);
+ ctx->hout = INVALID_HANDLE_VALUE;
+ }
+ ctx->ops->op_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 = ctx->closep;
+
+ switch (args->whence) {
+ case SEEK_SET:
+ new_current = args->offset;
+ break;
+
+ case SEEK_END:
+ if (ctx->end == 0) {
+ LARGE_INTEGER zero;
+ LARGE_INTEGER new_offset;
+
+ if (_zip_seek_win32(ctx->h, args->offset, SEEK_END, &ctx->error) < 0) {
+ return -1;
+ }
+ zero.QuadPart = 0;
+ if (!SetFilePointerEx(ctx->h, zero, &new_offset, FILE_CURRENT)) {
+ zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ new_current = new_offset.QuadPart;
+ 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 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
+ zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ ctx->current = (zip_uint64_t)new_current;
+
+ if (need_seek) {
+ if (_zip_seek_win32_u(ctx->h, ctx->current, 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_seek_win32(ctx->hout, args->offset, args->whence, &ctx->error) < 0) {
+ return -1;
+ }
+ return 0;
+ }
+
+ case ZIP_SOURCE_STAT: {
+ if (len < sizeof(ctx->st))
+ return -1;
+
+ if (ctx->st.valid != 0)
+ memcpy(data, &ctx->st, sizeof(ctx->st));
+ else {
+ DWORD win32err;
+ zip_stat_t *st;
+ HANDLE h;
+ int success;
+
+ st = (zip_stat_t *)data;
+
+ if (ctx->h != INVALID_HANDLE_VALUE) {
+ h = ctx->h;
+ }
+ else {
+ h = ctx->ops->op_open(ctx);
+ if (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
+ return -1;
+ }
+ }
+
+ success = _zip_stat_win32(h, st, ctx);
+ win32err = GetLastError();
+
+ /* We're done with the handle, so close it if we just opened it. */
+ if (h != ctx->h) {
+ CloseHandle(h);
+ }
+
+ if (success < 0) {
+ /* TODO: Is this the correct error to return in all cases? */
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(win32err));
+ return -1;
+ }
+ }
+ return sizeof(ctx->st);
+ }
+
+ case ZIP_SOURCE_SUPPORTS:
+ return ctx->supports;
+
+ case ZIP_SOURCE_TELL:
+ return (zip_int64_t)ctx->current;
+
+ case ZIP_SOURCE_TELL_WRITE:
+ {
+ LARGE_INTEGER zero;
+ LARGE_INTEGER offset;
+
+ zero.QuadPart = 0;
+ if (!SetFilePointerEx(ctx->hout, zero, &offset, FILE_CURRENT)) {
+ zip_error_set(&ctx->error, ZIP_ER_TELL, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return offset.QuadPart;
+ }
+
+ case ZIP_SOURCE_WRITE:
+ {
+ DWORD ret;
+ if (!WriteFile(ctx->hout, data, (DWORD)len, &ret, NULL) || ret != len) {
+ zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return (zip_int64_t)ret;
+ }
+
+ default:
+ zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
+ return -1;
+ }
+}
+
+
+static int
+_win32_create_temp_file(_zip_source_win32_read_file_t *ctx)
+{
+ zip_uint32_t value;
+ /*
+ Windows has GetTempFileName(), but it closes the file after
+ creation, leaving it open to a horrible race condition. So
+ we reinvent the wheel.
+ */
+ int i;
+ HANDLE th = INVALID_HANDLE_VALUE;
+ void *temp = NULL;
+ SECURITY_INFORMATION si;
+ SECURITY_ATTRIBUTES sa;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PSECURITY_ATTRIBUTES psa = NULL;
+ DWORD len;
+ BOOL success;
+
+ /*
+ Read the DACL from the original file, so we can copy it to the temp file.
+ If there is no original file, or if we can't read the DACL, we'll use the
+ default security descriptor.
+ */
+ if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
+ 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) {
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = FALSE;
+ sa.lpSecurityDescriptor = psd;
+ psa = &sa;
+ }
+ }
+
+ value = GetTickCount();
+ for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
+ th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
+ if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
+ break;
+ }
+
+ if (th == INVALID_HANDLE_VALUE) {
+ free(temp);
+ free(psd);
+ zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ free(psd);
+ ctx->hout = th;
+ ctx->tmpname = temp;
+
+ return 0;
+}
+
+
+static int
+_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error)
+{
+ if (offset > ZIP_INT64_MAX) {
+ zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
+ return -1;
+ }
+ return _zip_seek_win32(h, (zip_int64_t)offset, whence, error);
+}
+
+
+static int
+_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error)
+{
+ LARGE_INTEGER li;
+ DWORD method;
+
+ switch (whence) {
+ case SEEK_SET:
+ method = FILE_BEGIN;
+ break;
+ case SEEK_END:
+ method = FILE_END;
+ break;
+ case SEEK_CUR:
+ method = FILE_CURRENT;
+ break;
+ default:
+ zip_error_set(error, ZIP_ER_SEEK, EINVAL);
+ return -1;
+ }
+
+ li.QuadPart = (LONGLONG)offset;
+ if (!SetFilePointerEx(h, li, NULL, method)) {
+ zip_error_set(error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+_zip_win32_error_to_errno(DWORD win32err)
+{
+ /*
+ Note: This list isn't exhaustive, but should cover common cases.
+ */
+ switch (win32err) {
+ case ERROR_INVALID_PARAMETER:
+ return EINVAL;
+ case ERROR_FILE_NOT_FOUND:
+ return ENOENT;
+ case ERROR_INVALID_HANDLE:
+ return EBADF;
+ case ERROR_ACCESS_DENIED:
+ return EACCES;
+ case ERROR_FILE_EXISTS:
+ return EEXIST;
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return EMFILE;
+ case ERROR_DISK_FULL:
+ return ENOSPC;
+ default:
+ return 0;
+ }
+}
+
+
+static int
+_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx)
+{
+ FILETIME mtimeft;
+ time_t mtime;
+ LARGE_INTEGER size;
+ int regularp;
+
+ if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+ if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
+ return -1;
+ }
+
+ regularp = 0;
+ if (GetFileType(h) == FILE_TYPE_DISK) {
+ regularp = 1;
+ }
+
+ if (!GetFileSizeEx(h, &size)) {
+ zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
+ return -1;
+ }
+
+ zip_stat_init(st);
+ st->mtime = mtime;
+ st->valid |= ZIP_STAT_MTIME;
+ if (ctx->end != 0) {
+ st->size = ctx->end - ctx->start;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+ else if (regularp) {
+ st->size = (zip_uint64_t)size.QuadPart;
+ st->valid |= ZIP_STAT_SIZE;
+ }
+
+ return 0;
+}
+
+
+static int
+_zip_filetime_to_time_t(FILETIME ft, time_t *t)
+{
+ /*
+ Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
+ */
+ const zip_int64_t WINDOWS_TICK = 10000000LL;
+ const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
+ ULARGE_INTEGER li;
+ zip_int64_t secs;
+ time_t temp;
+
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
+
+ temp = (time_t)secs;
+ if (secs != (zip_int64_t)temp)
+ return -1;
+
+ *t = temp;
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_win32utf8.c b/src/Common/libzip/zip_source_win32utf8.c
new file mode 100644
index 00000000..004c66ac
--- /dev/null
+++ b/src/Common/libzip/zip_source_win32utf8.c
@@ -0,0 +1,79 @@
+/*
+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>
+
+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 <stdio.h>
+
+#include "zipint.h"
+#include "zipwin32.h"
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_file_create(fname, start, len, &za->error);
+}
+
+
+ZIP_EXTERN zip_source_t *
+zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
+{
+ int size;
+ wchar_t *wfname;
+ zip_source_t *source;
+
+ if (fname == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ /* Convert fname from UTF-8 to Windows-friendly UTF-16. */
+ size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, NULL, 0);
+ if (size == 0) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ if ((wfname = (wchar_t *)malloc(sizeof(wchar_t) * size)) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+ MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fname, -1, wfname, size);
+
+ source = zip_source_win32w_create(wfname, start, length, error);
+
+ free(wfname);
+ return source;
+}
diff --git a/src/Common/libzip/zip_source_win32w.c b/src/Common/libzip/zip_source_win32w.c
new file mode 100644
index 00000000..551aba5f
--- /dev/null
+++ b/src/Common/libzip/zip_source_win32w.c
@@ -0,0 +1,124 @@
+/*
+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.
+*/
+
+
+#include <stdio.h>
+
+#include "zipint.h"
+#include "zipwin32.h"
+
+static void * _win32_strdup_w(const void *str);
+static HANDLE _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);
+static int _win32_rename_temp_w(_zip_source_win32_read_file_t *ctx);
+static int _win32_remove_w(const void *fname);
+
+static _zip_source_win32_file_ops_t win32_ops_w = {
+ _win32_strdup_w,
+ _win32_open_w,
+ _win32_create_temp_w,
+ _win32_rename_temp_w,
+ _win32_remove_w
+};
+
+ZIP_EXTERN zip_source_t *
+zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len)
+{
+ if (za == NULL)
+ return NULL;
+
+ return zip_source_win32w_create(fname, start, len, &za->error);
+}
+
+
+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)
+{
+ if (fname == NULL || length < -1) {
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_w, error);
+}
+
+
+static void *
+_win32_strdup_w(const void *str)
+{
+ return _wcsdup((const wchar_t *)str);
+}
+
+
+static HANDLE
+_win32_open_w(_zip_source_win32_read_file_t *ctx)
+{
+ return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+}
+
+
+static HANDLE
+_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
+{
+ int len;
+
+ len = wcslen((const wchar_t *)ctx->fname) + 10;
+ if (*temp == NULL) {
+ if ((*temp = malloc(sizeof(wchar_t) * len)) == NULL) {
+ zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
+ return INVALID_HANDLE_VALUE;
+ }
+ }
+ if (_snwprintf((wchar_t *)*temp, len, L"%s.%08x", (const wchar_t *)ctx->fname, value) != len - 1) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
+}
+
+
+static int
+_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx)
+{
+ if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
+ return -1;
+ return 0;
+}
+
+
+static int
+_win32_remove_w(const void *fname)
+{
+ DeleteFileW((const wchar_t *)fname);
+ return 0;
+}
diff --git a/src/Common/libzip/zip_source_window.c b/src/Common/libzip/zip_source_window.c
new file mode 100644
index 00000000..f02d048c
--- /dev/null
+++ b/src/Common/libzip/zip_source_window.c
@@ -0,0 +1,253 @@
+/*
+ zip_source_window.c -- return part of lower source
+ Copyright (C) 2012-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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+struct window {
+ zip_uint64_t start;
+ zip_uint64_t end;
+ zip_uint64_t offset;
+ zip_stat_t stat;
+ zip_error_t error;
+ zip_int64_t supports;
+ bool needs_seek;
+};
+
+static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
+
+
+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_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)
+{
+ struct window *ctx;
+
+ if (src == NULL || start + length < start) {
+ 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;
+ }
+
+ ctx->start = start;
+ ctx->end = start + length;
+ zip_stat_init(&ctx->stat);
+ 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->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;
+ }
+ }
+
+ return zip_source_layered_create(src, window_read, ctx, error);
+}
+
+
+int
+_zip_source_set_source_archive(zip_source_t *src, zip_t *za)
+{
+ src->source_archive = za;
+ return _zip_register_source(za, src);
+}
+
+
+/* called by zip_discard to avoid operating on file from closed archive */
+void
+_zip_source_invalidate(zip_source_t *src)
+{
+ src->source_closed = 1;
+
+ if (zip_error_code_zip(&src->error) == ZIP_ER_OK) {
+ zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0);
+ }
+}
+
+
+static zip_int64_t
+window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
+{
+ struct window *ctx;
+ zip_int64_t ret;
+ zip_uint64_t n, i;
+ char b[8192];
+
+ ctx = (struct window *)_ctx;
+
+ 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;
+ }
+}
+
+
+void
+_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;
+ }
+ }
+}
+
+
+int
+_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;
+ }
+
+ 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
new file mode 100644
index 00000000..c98f5679
--- /dev/null
+++ b/src/Common/libzip/zip_source_write.c
@@ -0,0 +1,47 @@
+/*
+ zip_source_write.c -- start a new file for writing
+ 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
+ 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"
+
+
+ZIP_EXTERN zip_int64_t
+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;
+ }
+
+ 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
new file mode 100644
index 00000000..e172ca20
--- /dev/null
+++ b/src/Common/libzip/zip_source_zip.c
@@ -0,0 +1,59 @@
+/*
+ zip_source_zip.c -- create data source from zip file
+ Copyright (C) 1999-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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+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)
+{
+ if (len < -1) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if (len == -1)
+ len = 0;
+
+ if (start == 0 && len == 0)
+ flags |= ZIP_FL_COMPRESSED;
+ else
+ flags &= ~ZIP_FL_COMPRESSED;
+
+ return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL);
+}
diff --git a/src/Common/libzip/zip_source_zip_new.c b/src/Common/libzip/zip_source_zip_new.c
new file mode 100644
index 00000000..40f1195f
--- /dev/null
+++ b/src/Common/libzip/zip_source_zip_new.c
@@ -0,0 +1,173 @@
+/*
+ zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip
+ Copyright (C) 2012-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>
+
+ 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>
+
+#include "zipint.h"
+
+
+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_t *src, *s2;
+ zip_uint64_t offset;
+ struct zip_stat st;
+
+ if (za == NULL)
+ return NULL;
+
+ if (srcza == NULL || srcidx >= srcza->nentry) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ 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);
+ return NULL;
+ }
+
+ if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) {
+ zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
+
+ if (flags & ZIP_FL_ENCRYPTED)
+ flags |= ZIP_FL_COMPRESSED;
+
+ if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ /* overflow or past end of file */
+ if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ enc_impl = NULL;
+ if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) {
+ if (password == NULL) {
+ zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
+ return NULL;
+ }
+ if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) {
+ zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+ return NULL;
+ }
+ }
+
+ 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)) == 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) {
+ return zip_source_buffer(za, NULL, 0, 0);
+ }
+
+ if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) {
+ struct zip_stat st2;
+
+ st2.size = len ? len : st.size-start;
+ st2.comp_size = st2.size;
+ 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) {
+ return NULL;
+ }
+ }
+ else {
+ if ((src = _zip_source_window_new(srcza->src, offset, st.comp_size, &st, &za->error)) == NULL) {
+ return NULL;
+ }
+ }
+
+ if (_zip_source_set_source_archive(src, srcza) < 0) {
+ zip_source_free(src);
+ return NULL;
+ }
+
+ /* creating a layered source calls zip_keep() on the lower layer, so we free it */
+
+ if (enc_impl) {
+ s2 = enc_impl(za, src, st.encryption_method, 0, password);
+ zip_source_free(src);
+ if (s2 == NULL) {
+ return NULL;
+ }
+ src = s2;
+ }
+ if (comp_impl) {
+ s2 = comp_impl(za, src, st.comp_method, 0);
+ zip_source_free(src);
+ if (s2 == NULL) {
+ return NULL;
+ }
+ src = s2;
+ }
+ 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 */
+ s2 = zip_source_crc(za, src, 1);
+ zip_source_free(src);
+ if (s2 == NULL) {
+ return NULL;
+ }
+ src = s2;
+ }
+
+ if (start+len > 0 && (comp_impl || enc_impl)) {
+ s2 = zip_source_window(za, src, start, len ? len : st.size-start);
+ zip_source_free(src);
+ if (s2 == NULL) {
+ return NULL;
+ }
+ src = s2;
+ }
+
+ return src;
+}
diff --git a/src/Common/libzip/zip_stat.c b/src/Common/libzip/zip_stat.c
new file mode 100644
index 00000000..cf8e5661
--- /dev/null
+++ b/src/Common/libzip/zip_stat.c
@@ -0,0 +1,47 @@
+/*
+ zip_stat.c -- get information about file by name
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN int
+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)
+ return -1;
+
+ return zip_stat_index(za, (zip_uint64_t)idx, flags, st);
+}
diff --git a/src/Common/libzip/zip_stat_index.c b/src/Common/libzip/zip_stat_index.c
new file mode 100644
index 00000000..601e3f70
--- /dev/null
+++ b/src/Common/libzip/zip_stat_index.c
@@ -0,0 +1,86 @@
+/*
+ zip_stat_index.c -- get information about file by index
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN int
+zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags,
+ zip_stat_t *st)
+{
+ const char *name;
+ zip_dirent_t *de;
+
+ if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL)
+ return -1;
+
+ 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 (zip_source_stat(za->entry[index].source, st) < 0) {
+ zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+ return -1;
+ }
+ }
+ else {
+ zip_stat_init(st);
+
+ st->crc = de->crc;
+ st->size = de->uncomp_size;
+ st->mtime = de->last_mod;
+ st->comp_size = de->comp_size;
+ st->comp_method = (zip_uint16_t)de->comp_method;
+ if (de->bitflags & ZIP_GPBF_ENCRYPTED) {
+ if (de->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
+ /* TODO */
+ st->encryption_method = ZIP_EM_UNKNOWN;
+ }
+ else
+ st->encryption_method = ZIP_EM_TRAD_PKWARE;
+ }
+ else
+ st->encryption_method = ZIP_EM_NONE;
+ st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
+ |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
+ }
+
+ st->index = index;
+ st->name = 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
new file mode 100644
index 00000000..6b7d6337
--- /dev/null
+++ b/src/Common/libzip/zip_stat_init.c
@@ -0,0 +1,85 @@
+/*
+ zip_stat_init.c -- initialize struct zip_stat.
+ Copyright (C) 2006-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
+ 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 <string.h>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN void
+zip_stat_init(zip_stat_t *st)
+{
+ st->valid = 0;
+ st->name = NULL;
+ st->index = ZIP_UINT64_MAX;
+ st->crc = 0;
+ st->mtime = (time_t)-1;
+ st->size = 0;
+ st->comp_size = 0;
+ st->comp_method = ZIP_CM_STORE;
+ st->encryption_method = ZIP_EM_NONE;
+}
+
+
+int
+_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;
+ }
+ if (src->valid & ZIP_STAT_SIZE) {
+ dst->size = src->size;
+ }
+ if (src->valid & ZIP_STAT_COMP_SIZE) {
+ dst->comp_size = src->comp_size;
+ }
+ if (src->valid & ZIP_STAT_MTIME) {
+ dst->mtime = src->mtime;
+ }
+ if (src->valid & ZIP_STAT_CRC) {
+ dst->crc = src->crc;
+ }
+ if (src->valid & ZIP_STAT_COMP_METHOD) {
+ dst->comp_method = src->comp_method;
+ }
+ if (src->valid & ZIP_STAT_ENCRYPTION_METHOD) {
+ dst->encryption_method = src->encryption_method;
+ }
+ if (src->valid & ZIP_STAT_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
new file mode 100644
index 00000000..98c4f6b1
--- /dev/null
+++ b/src/Common/libzip/zip_strerror.c
@@ -0,0 +1,42 @@
+/*
+ zip_sterror.c -- get string representation of zip error
+ Copyright (C) 1999-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
+ 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"
+
+
+ZIP_EXTERN const char *
+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
new file mode 100644
index 00000000..307a425f
--- /dev/null
+++ b/src/Common/libzip/zip_string.c
@@ -0,0 +1,188 @@
+/*
+ zip_string.c -- string handling (with encoding)
+ Copyright (C) 2012-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
+ 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>
+#include <string.h>
+
+#include "zipint.h"
+
+
+zip_uint32_t
+_zip_string_crc32(const zip_string_t *s)
+{
+ zip_uint32_t crc;
+
+ crc = (zip_uint32_t)crc32(0L, Z_NULL, 0);
+
+ if (s != NULL)
+ crc = (zip_uint32_t)crc32(crc, s->raw, s->length);
+
+ return crc;
+}
+
+
+int
+_zip_string_equal(const zip_string_t *a, const zip_string_t *b)
+{
+ if (a == NULL || b == NULL)
+ return a == b;
+
+ if (a->length != b->length)
+ return 0;
+
+ /* TODO: encoding */
+
+ return (memcmp(a->raw, b->raw, a->length) == 0);
+}
+
+
+void
+_zip_string_free(zip_string_t *s)
+{
+ if (s == NULL)
+ return;
+
+ free(s->raw);
+ free(s->converted);
+ free(s);
+}
+
+
+const zip_uint8_t *
+_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] = "";
+
+ if (string == NULL) {
+ if (lenp)
+ *lenp = 0;
+ return empty;
+ }
+
+ if ((flags & ZIP_FL_ENC_RAW) == 0) {
+ /* start guessing */
+ if (string->encoding == ZIP_ENCODING_UNKNOWN)
+ _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN);
+
+ 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)
+ return NULL;
+ }
+ if (lenp)
+ *lenp = string->converted_length;
+ return string->converted;
+ }
+ }
+
+ if (lenp)
+ *lenp = string->length;
+ return string->raw;
+}
+
+
+zip_uint16_t
+_zip_string_length(const zip_string_t *s)
+{
+ if (s == NULL)
+ return 0;
+
+ return s->length;
+}
+
+
+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_t *s;
+ zip_encoding_type_t expected_encoding;
+
+ if (length == 0)
+ return NULL;
+
+ switch (flags & ZIP_FL_ENCODING_ALL) {
+ case ZIP_FL_ENC_GUESS:
+ expected_encoding = ZIP_ENCODING_UNKNOWN;
+ break;
+ case ZIP_FL_ENC_UTF_8:
+ expected_encoding = ZIP_ENCODING_UTF8_KNOWN;
+ break;
+ case ZIP_FL_ENC_CP437:
+ expected_encoding = ZIP_ENCODING_CP437;
+ break;
+ default:
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+
+ if ((s=(zip_string_t *)malloc(sizeof(*s))) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ if ((s->raw=(zip_uint8_t *)malloc((size_t)(length+1))) == NULL) {
+ free(s);
+ return NULL;
+ }
+
+ memcpy(s->raw, raw, length);
+ s->raw[length] = '\0';
+ s->length = length;
+ s->encoding = ZIP_ENCODING_UNKNOWN;
+ s->converted = NULL;
+ s->converted_length = 0;
+
+ if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
+ if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) {
+ _zip_string_free(s);
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
+ }
+ }
+
+ return s;
+}
+
+
+int
+_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
new file mode 100644
index 00000000..5ef54621
--- /dev/null
+++ b/src/Common/libzip/zip_unchange.c
@@ -0,0 +1,95 @@
+/*
+ zip_unchange.c -- undo changes to file in zip archive
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_unchange(zip_t *za, zip_uint64_t idx)
+{
+ return _zip_unchange(za, idx, 0);
+}
+
+
+int
+_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) {
+ zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+ return -1;
+ }
+
+ if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) {
+ if (za->entry[idx].orig != NULL) {
+ if ((orig_name=_zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) {
+ return -1;
+ }
+
+ i = _zip_name_locate(za, orig_name, 0, NULL);
+ if (i >= 0 && (zip_uint64_t)i != idx) {
+ zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
+ }
+ }
+ else {
+ orig_name = NULL;
+ }
+
+ if ((changed_name=_zip_get_name(za, idx, 0, &za->error)) == NULL) {
+ return -1;
+ }
+
+ if (orig_name) {
+ if (_zip_hash_add(za->names, (const zip_uint8_t *)orig_name, idx, 0, &za->error) == false) {
+ return -1;
+ }
+ }
+ if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) {
+ _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL);
+ return -1;
+ }
+ }
+
+ _zip_dirent_free(za->entry[idx].changes);
+ za->entry[idx].changes = NULL;
+
+ _zip_unchange_data(za->entry+idx);
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_unchange_all.c b/src/Common/libzip/zip_unchange_all.c
new file mode 100644
index 00000000..dc89f7fd
--- /dev/null
+++ b/src/Common/libzip/zip_unchange_all.c
@@ -0,0 +1,55 @@
+/*
+ zip_unchange.c -- undo changes to all files in zip archive
+ 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>
+
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_unchange_all(zip_t *za)
+{
+ int ret;
+ zip_uint64_t i;
+
+ _zip_hash_revert(za->names);
+
+ ret = 0;
+ for (i=0; i<za->nentry; i++)
+ ret |= _zip_unchange(za, i, 1);
+
+ ret |= zip_unchange_archive(za);
+
+ return ret;
+}
diff --git a/src/Common/libzip/zip_unchange_archive.c b/src/Common/libzip/zip_unchange_archive.c
new file mode 100644
index 00000000..920255cc
--- /dev/null
+++ b/src/Common/libzip/zip_unchange_archive.c
@@ -0,0 +1,52 @@
+/*
+ zip_unchange_archive.c -- undo global changes to ZIP archive
+ Copyright (C) 2006-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
+ 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>
+
+#include "zipint.h"
+
+
+ZIP_EXTERN int
+zip_unchange_archive(zip_t *za)
+{
+ if (za->comment_changed) {
+ _zip_string_free(za->comment_changes);
+ za->comment_changes = NULL;
+ za->comment_changed = 0;
+ }
+
+ za->ch_flags = za->flags;
+
+ return 0;
+}
diff --git a/src/Common/libzip/zip_unchange_data.c b/src/Common/libzip/zip_unchange_data.c
new file mode 100644
index 00000000..839d9a3c
--- /dev/null
+++ b/src/Common/libzip/zip_unchange_data.c
@@ -0,0 +1,55 @@
+/*
+ zip_unchange_data.c -- undo helper function
+ Copyright (C) 1999-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
+ 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"
+
+void
+_zip_unchange_data(zip_entry_t *ze)
+{
+ if (ze->source) {
+ zip_source_free(ze->source);
+ ze->source = NULL;
+ }
+
+ if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) {
+ ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
+ if (ze->changes->changed == 0) {
+ _zip_dirent_free(ze->changes);
+ ze->changes = NULL;
+ }
+ }
+
+ ze->deleted = 0;
+}
+
diff --git a/src/Common/libzip/zip_utf-8.c b/src/Common/libzip/zip_utf-8.c
new file mode 100644
index 00000000..f38eea04
--- /dev/null
+++ b/src/Common/libzip/zip_utf-8.c
@@ -0,0 +1,249 @@
+/*
+ zip_utf-8.c -- UTF-8 support functions for libzip
+ Copyright (C) 2011-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
+ 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 <stdlib.h>
+
+
+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,
+
+ /* 0x10 - 0x1F */
+ 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,
+
+ /* 0x30 - 0x3F */
+ 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,
+
+ /* 0x50 - 0x5F */
+ 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,
+
+ /* 0x70 - 0x7F */
+ 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,
+
+ /* 0x90 - 0x9F */
+ 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,
+
+ /* 0xB0 - 0xBF */
+ 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,
+
+ /* 0xD0 - 0xDF */
+ 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,
+
+ /* 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
+#define UTF_8_CONTINUE_MATCH 0x80
+
+
+zip_encoding_type_t
+_zip_guess_encoding(zip_string_t *str, zip_encoding_type_t expected_encoding)
+{
+ zip_encoding_type_t enc;
+ const zip_uint8_t *name;
+ zip_uint32_t i, j, ulen;
+
+ if (str == NULL)
+ return ZIP_ENCODING_ASCII;
+
+ name = str->raw;
+
+ if (str->encoding != ZIP_ENCODING_UNKNOWN)
+ enc = str->encoding;
+ else {
+ enc = ZIP_ENCODING_ASCII;
+ for (i=0; i<str->length; i++) {
+ if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t')
+ continue;
+
+ enc = ZIP_ENCODING_UTF8_GUESSED;
+ if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH)
+ ulen = 1;
+ else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH)
+ ulen = 2;
+ else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH)
+ ulen = 3;
+ else {
+ enc = ZIP_ENCODING_CP437;
+ break;
+ }
+
+ if (i + ulen >= str->length) {
+ enc = ZIP_ENCODING_CP437;
+ break;
+ }
+
+ for (j=1; j<=ulen; j++) {
+ if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) {
+ enc = ZIP_ENCODING_CP437;
+ goto done;
+ }
+ }
+ i += ulen;
+ }
+ }
+
+done:
+ str->encoding = enc;
+
+ if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
+ if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED)
+ str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN;
+
+ if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII)
+ return ZIP_ENCODING_ERROR;
+ }
+
+ return enc;
+}
+
+
+static zip_uint32_t
+_zip_unicode_to_utf8_len(zip_uint32_t codepoint)
+{
+ if (codepoint < 0x0080)
+ return 1;
+ if (codepoint < 0x0800)
+ return 2;
+ if (codepoint < 0x10000)
+ return 3;
+ return 4;
+}
+
+
+static zip_uint32_t
+_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf)
+{
+ if (codepoint < 0x0080) {
+ buf[0] = codepoint & 0xff;
+ return 1;
+ }
+ if (codepoint < 0x0800) {
+ buf[0] = (zip_uint8_t)(UTF_8_LEN_2_MATCH | ((codepoint >> 6) & 0x1f));
+ buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f));
+ return 2;
+ }
+ if (codepoint < 0x10000) {
+ buf[0] = (zip_uint8_t)(UTF_8_LEN_3_MATCH | ((codepoint >> 12) & 0x0f));
+ buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f));
+ buf[2] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f));
+ return 3;
+ }
+ buf[0] = (zip_uint8_t)(UTF_8_LEN_4_MATCH | ((codepoint >> 18) & 0x07));
+ buf[1] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 12) & 0x3f));
+ buf[2] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f));
+ buf[3] = (zip_uint8_t)(UTF_8_CONTINUE_MATCH | (codepoint & 0x3f));
+ return 4;
+}
+
+
+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_uint8_t *cp437buf = (zip_uint8_t *)_cp437buf;
+ zip_uint8_t *utf8buf;
+ zip_uint32_t buflen, i, offset;
+
+ if (len == 0) {
+ if (utf8_lenp)
+ *utf8_lenp = 0;
+ return NULL;
+ }
+
+ buflen = 1;
+ 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) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+
+ offset = 0;
+ for (i=0; i<len; i++)
+ offset += _zip_unicode_to_utf8(_cp437_to_unicode[cp437buf[i]],
+ utf8buf+offset);
+
+ utf8buf[buflen-1] = 0;
+ if (utf8_lenp)
+ *utf8_lenp = buflen-1;
+ return utf8buf;
+}
diff --git a/src/Common/libzip/zipconf.h b/src/Common/libzip/zipconf.h
new file mode 100644
index 00000000..3c506aea
--- /dev/null
+++ b/src/Common/libzip/zipconf.h
@@ -0,0 +1,121 @@
+#ifndef _HAD_ZIPCONF_H
+#define _HAD_ZIPCONF_H
+
+/*
+ zipconf.h -- platform specific include file
+
+ This file was generated automatically by CMake
+ based on ../cmake-zipconf.h.in.
+ */
+
+/* #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
+
+#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
+
+#define ZIP_INT8_MIN -0x80
+#define ZIP_INT8_MAX 0x7f
+#define ZIP_UINT8_MAX 0xff
+
+#define ZIP_INT16_MIN -0x8000
+#define ZIP_INT16_MAX 0x7fff
+#define ZIP_UINT16_MAX 0xffff
+
+#define ZIP_INT32_MIN -0x80000000L
+#define ZIP_INT32_MAX 0x7fffffffL
+#define ZIP_UINT32_MAX 0xffffffffLU
+
+#define ZIP_INT64_MIN (-ZIP_INT64_MAX-1LL)
+#define ZIP_INT64_MAX 0x7fffffffffffffffLL
+#define ZIP_UINT64_MAX 0xffffffffffffffffULL
+
+#endif /* zipconf.h */
diff --git a/src/Common/libzip/zipint.h b/src/Common/libzip/zipint.h
new file mode 100644
index 00000000..6939d73f
--- /dev/null
+++ b/src/Common/libzip/zipint.h
@@ -0,0 +1,465 @@
+#ifndef _HAD_ZIPINT_H
+#define _HAD_ZIPINT_H
+
+/*
+ zipint.h -- internal declarations.
+ 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "compat.h"
+
+#include <zlib.h>
+
+#ifndef _ZIP_COMPILING_DEPRECATED
+#define ZIP_DISABLE_DEPRECATED
+#endif
+
+#include "zip.h"
+
+#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 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 EFZIP64SIZE 28
+
+#define ZIP_CM_REPLACED_DEFAULT (-2)
+
+#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
+
+#define ZIP_EF_UTF_8_COMMENT 0x6375
+#define ZIP_EF_UTF_8_NAME 0x7075
+#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_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)
+/* 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_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/* This section contains API that won't materialize like this. It's
+ placed in the internal section, pending cleanup. */
+
+/* flags for compression and encryption sources */
+
+#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */
+#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */
+
+
+typedef zip_source_t *(*zip_compression_implementation)(zip_t *, zip_source_t *, zip_int32_t, int);
+typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
+
+zip_compression_implementation _zip_get_compression_implementation(zip_int32_t);
+zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t);
+
+
+
+/* This API is not final yet, but we need it internally, so it's private for now. */
+
+const zip_uint8_t *zip_get_extra_field_by_id(zip_t *, int, int, zip_uint16_t, int, zip_uint16_t *);
+
+/* This section contains API that is of limited use until support for
+ user-supplied compression/encryption implementation is finished.
+ Thus we will keep it private for now. */
+
+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_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_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *);
+zip_source_t *zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error);
+zip_source_t *zip_source_pkware(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
+int zip_source_remove(zip_source_t *);
+zip_int64_t zip_source_supports(zip_source_t *src);
+zip_source_t *zip_source_window(zip_t *, zip_source_t *, zip_uint64_t, zip_uint64_t);
+
+
+/* error source for layered sources */
+
+enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
+
+/* directory entry: general purpose bit flags */
+
+#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 */
+
+
+/* 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_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)
+
+
+/* encoding type */
+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 */
+};
+
+typedef enum zip_encoding_type zip_encoding_type_t;
+
+#ifndef ZIP_HASH_TABLE_SIZE
+#define ZIP_HASH_TABLE_SIZE 8192
+#endif
+
+struct zip_hash;
+
+typedef struct zip_cdir zip_cdir_t;
+typedef struct zip_dirent zip_dirent_t;
+typedef struct zip_entry zip_entry_t;
+typedef struct zip_extra_field zip_extra_field_t;
+typedef struct zip_string zip_string_t;
+typedef struct zip_buffer zip_buffer_t;
+typedef struct zip_hash zip_hash_t;
+
+/* zip archive, part of API */
+
+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 */
+
+ unsigned int flags; /* archive global flags */
+ unsigned int ch_flags; /* changed archive global flags */
+
+ 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_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 */
+
+ zip_hash_t *names; /* hash table for name lookup */
+
+ char *tempdir; /* custom temp dir (needed e.g. for OS X sandboxing) */
+};
+
+/* file in zip archive, part of API */
+
+struct zip_file {
+ zip_t *za; /* zip archive containing this file */
+ zip_error_t error; /* error information */
+ bool eof;
+ zip_source_t *src; /* data source */
+};
+
+/* zip archive directory entry (central or local) */
+
+#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_ALL 0xffffu
+
+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 */
+
+ 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 archive central directory */
+
+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 */
+};
+
+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_uint8_t *data;
+};
+
+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 */
+};
+typedef enum zip_source_write_state zip_source_write_state_t;
+
+struct zip_source {
+ zip_source_t *src;
+ union {
+ zip_source_callback f;
+ zip_source_layered_callback l;
+ } cb;
+ void *ud;
+ 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 */
+ unsigned int refcount;
+};
+
+#define ZIP_SOURCE_IS_OPEN_READING(src) ((src)->open_count > 0)
+#define ZIP_SOURCE_IS_OPEN_WRITING(src) ((src)->write_state == ZIP_SOURCE_WRITE_OPEN)
+#define ZIP_SOURCE_IS_LAYERED(src) ((src)->src != NULL)
+
+/* entry in zip archive directory */
+
+struct zip_entry {
+ zip_dirent_t *orig;
+ zip_dirent_t *changes;
+ zip_source_t *source;
+ bool deleted;
+};
+
+
+/* file or archive comment, or filename */
+
+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 */
+};
+
+
+/* bounds checked access to memory buffer */
+
+struct zip_buffer {
+ bool ok;
+ bool free_data;
+
+ zip_uint8_t *data;
+ zip_uint64_t size;
+ zip_uint64_t offset;
+};
+
+/* which files to write in which order */
+
+struct zip_filelist {
+ zip_uint64_t idx;
+/* TODO const char *name; */
+};
+
+typedef struct zip_filelist zip_filelist_t;
+
+
+extern const char * const _zip_err_str[];
+extern const int _zip_nerr_str;
+extern const int _zip_err_type[];
+
+
+#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f)))
+
+#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL)
+
+#define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY)
+
+
+zip_int64_t _zip_add_entry(zip_t *);
+
+zip_uint8_t *_zip_buffer_data(zip_buffer_t *buffer);
+bool _zip_buffer_eof(zip_buffer_t *buffer);
+void _zip_buffer_free(zip_buffer_t *buffer);
+zip_uint8_t *_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length);
+zip_uint16_t _zip_buffer_get_16(zip_buffer_t *buffer);
+zip_uint32_t _zip_buffer_get_32(zip_buffer_t *buffer);
+zip_uint64_t _zip_buffer_get_64(zip_buffer_t *buffer);
+zip_uint8_t _zip_buffer_get_8(zip_buffer_t *buffer);
+zip_uint64_t _zip_buffer_left(zip_buffer_t *buffer);
+zip_buffer_t *_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_uint64_t _zip_buffer_offset(zip_buffer_t *buffer);
+bool _zip_buffer_ok(zip_buffer_t *buffer);
+int _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);
+int _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);
+int _zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i);
+int _zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length);
+int _zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset);
+zip_uint64_t _zip_buffer_size(zip_buffer_t *buffer);
+
+int _zip_cdir_compute_crc(zip_t *, uLong *);
+void _zip_cdir_free(zip_cdir_t *);
+zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
+zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors);
+void _zip_deregister_source(zip_t *za, zip_source_t *src);
+
+zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
+void _zip_dirent_free(zip_dirent_t *);
+void _zip_dirent_finalize(zip_dirent_t *);
+void _zip_dirent_init(zip_dirent_t *);
+bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t);
+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);
+zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t, zip_error_t *);
+int _zip_dirent_write(zip_t *za, zip_dirent_t *dirent, zip_flags_t flags);
+
+zip_extra_field_t *_zip_ef_clone(const zip_extra_field_t *, zip_error_t *);
+zip_extra_field_t *_zip_ef_delete_by_id(zip_extra_field_t *, zip_uint16_t, zip_uint16_t, zip_flags_t);
+void _zip_ef_free(zip_extra_field_t *);
+const zip_uint8_t *_zip_ef_get_by_id(const zip_extra_field_t *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, zip_error_t *);
+zip_extra_field_t *_zip_ef_merge(zip_extra_field_t *, zip_extra_field_t *);
+zip_extra_field_t *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t);
+bool _zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zip_extra_field_t **, zip_error_t *);
+zip_extra_field_t *_zip_ef_remove_internal(zip_extra_field_t *);
+zip_uint16_t _zip_ef_size(const zip_extra_field_t *, zip_flags_t);
+int _zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags);
+
+void _zip_entry_finalize(zip_entry_t *);
+void _zip_entry_init(zip_entry_t *);
+
+void _zip_error_clear(zip_error_t *);
+void _zip_error_get(const zip_error_t *, int *, int *);
+
+void _zip_error_copy(zip_error_t *dst, const zip_error_t *src);
+void _zip_error_set_from_source(zip_error_t *, zip_source_t *);
+
+const zip_uint8_t *_zip_extract_extra_field_by_id(zip_error_t *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *);
+
+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_offset(const zip_t *, zip_uint64_t, zip_error_t *);
+
+int _zip_filerange_crc(zip_source_t *src, zip_uint64_t offset, zip_uint64_t length, uLong *crcp, zip_error_t *error);
+
+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 *);
+
+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);
+bool _zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *key, zip_error_t *error);
+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_t *_zip_open(zip_source_t *, unsigned int, zip_error_t *);
+
+int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error);
+int _zip_read_at_offset(zip_source_t *src, zip_uint64_t offset, unsigned char *b, size_t length, zip_error_t *error);
+zip_uint8_t *_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error);
+int _zip_read_local_ef(zip_t *, zip_uint64_t);
+zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t lenght, bool nulp, zip_error_t *error);
+int _zip_register_source(zip_t *za, zip_source_t *src);
+
+void _zip_set_open_error(int *zep, const zip_error_t *err, int ze);
+
+zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
+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_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_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *);
+
+int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
+int _zip_string_equal(const zip_string_t *, const zip_string_t *);
+void _zip_string_free(zip_string_t *);
+zip_uint32_t _zip_string_crc32(const zip_string_t *);
+const zip_uint8_t *_zip_string_get(zip_string_t *, zip_uint32_t *, zip_flags_t, zip_error_t *);
+zip_uint16_t _zip_string_length(const zip_string_t *);
+zip_string_t *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, zip_error_t *);
+int _zip_string_write(zip_t *za, const zip_string_t *string);
+
+int _zip_changed(const zip_t *, zip_uint64_t *);
+const char *_zip_get_name(zip_t *, zip_uint64_t, zip_flags_t, zip_error_t *);
+int _zip_local_header_read(zip_t *, int);
+void *_zip_memdup(const void *, size_t, zip_error_t *);
+zip_int64_t _zip_name_locate(zip_t *, const char *, zip_flags_t, zip_error_t *);
+zip_t *_zip_new(zip_error_t *);
+
+zip_int64_t _zip_file_replace(zip_t *, zip_uint64_t, const char *, zip_source_t *, zip_flags_t);
+int _zip_set_name(zip_t *, zip_uint64_t, const char *, zip_flags_t);
+void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
+int _zip_unchange(zip_t *, zip_uint64_t, int);
+void _zip_unchange_data(zip_entry_t *);
+int _zip_write(zip_t *za, const void *data, zip_uint64_t length);
+
+#endif /* zipint.h */
diff --git a/src/Common/libzip/zipwin32.h b/src/Common/libzip/zipwin32.h
new file mode 100644
index 00000000..60f8d0cf
--- /dev/null
+++ b/src/Common/libzip/zipwin32.h
@@ -0,0 +1,82 @@
+#ifndef _HAD_ZIPWIN32_H
+#define _HAD_ZIPWIN32_H
+
+/*
+ zipwin32.h -- internal declarations for Windows.
+ 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>
+
+ 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 */
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+
+/* context for Win32 source */
+
+struct _zip_source_win32_file_ops;
+
+struct _zip_source_win32_read_file {
+ zip_error_t error; /* last error information */
+ zip_int64_t supports;
+
+ /* operations */
+ struct _zip_source_win32_file_ops *ops;
+
+ /* 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 */
+
+ /* writing */
+ void *tmpname; /* name of temp file - ANSI (char *) or Unicode (wchar_t *) */
+ void *hout; /* HANDLE for output file */
+};
+
+typedef struct _zip_source_win32_read_file _zip_source_win32_read_file_t;
+
+/* internal operations for Win32 source */
+
+struct _zip_source_win32_file_ops {
+ void *(*op_strdup)(const void *);
+ void *(*op_open)(_zip_source_win32_read_file_t *);
+ void *(*op_create_temp)(_zip_source_win32_read_file_t *, void **, zip_uint32_t, PSECURITY_ATTRIBUTES);
+ int (*op_rename_temp)(_zip_source_win32_read_file_t *);
+ int (*op_remove)(const void *);
+};
+
+typedef struct _zip_source_win32_file_ops _zip_source_win32_file_ops_t;
+
+zip_source_t *_zip_source_win32_handle_or_name(const void *, void *, zip_uint64_t, zip_int64_t, int, const zip_stat_t *, _zip_source_win32_file_ops_t *, zip_error_t *);
+
+#endif /* zipwin32.h */