Windows: update libzip to latest version 1.7.3 (close issue #656)

This commit is contained in:
Mounir IDRASSI 2020-07-24 19:39:26 +02:00
parent 5cf7d946d2
commit 948a871c73
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F
49 changed files with 2508 additions and 2730 deletions

View File

@ -19,7 +19,6 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libzip\mkstemp.c" />
<ClCompile Include="libzip\zip_add.c" />
<ClCompile Include="libzip\zip_add_dir.c" />
<ClCompile Include="libzip\zip_add_entry.c" />
@ -72,6 +71,7 @@
<ClCompile Include="libzip\zip_name_locate.c" />
<ClCompile Include="libzip\zip_new.c" />
<ClCompile Include="libzip\zip_open.c" />
<ClCompile Include="libzip\zip_pkware.c" />
<ClCompile Include="libzip\zip_progress.c" />
<ClCompile Include="libzip\zip_rename.c" />
<ClCompile Include="libzip\zip_replace.c" />
@ -90,16 +90,21 @@
<ClCompile Include="libzip\zip_source_commit_write.c" />
<ClCompile Include="libzip\zip_source_compress.c" />
<ClCompile Include="libzip\zip_source_crc.c" />
<ClCompile Include="libzip\zip_source_deflate.c" />
<ClCompile Include="libzip\zip_source_error.c" />
<ClCompile Include="libzip\zip_source_filep.c" />
<ClCompile Include="libzip\zip_source_file_common.c" />
<ClCompile Include="libzip\zip_source_file_stdio.c" />
<ClCompile Include="libzip\zip_source_file_win32.c" />
<ClCompile Include="libzip\zip_source_file_win32_named.c" />
<ClCompile Include="libzip\zip_source_file_win32_utf16.c" />
<ClCompile Include="libzip\zip_source_file_win32_utf8.c" />
<ClCompile Include="libzip\zip_source_free.c" />
<ClCompile Include="libzip\zip_source_function.c" />
<ClCompile Include="libzip\zip_source_get_compression_flags.c" />
<ClCompile Include="libzip\zip_source_get_file_attributes.c" />
<ClCompile Include="libzip\zip_source_is_deleted.c" />
<ClCompile Include="libzip\zip_source_layered.c" />
<ClCompile Include="libzip\zip_source_open.c" />
<ClCompile Include="libzip\zip_source_pkware.c" />
<ClCompile Include="libzip\zip_source_pkware_decode.c" />
<ClCompile Include="libzip\zip_source_pkware_encode.c" />
<ClCompile Include="libzip\zip_source_read.c" />
<ClCompile Include="libzip\zip_source_remove.c" />
<ClCompile Include="libzip\zip_source_rollback_write.c" />
@ -109,10 +114,6 @@
<ClCompile Include="libzip\zip_source_supports.c" />
<ClCompile Include="libzip\zip_source_tell.c" />
<ClCompile Include="libzip\zip_source_tell_write.c" />
<ClCompile Include="libzip\zip_source_win32a.c" />
<ClCompile Include="libzip\zip_source_win32handle.c" />
<ClCompile Include="libzip\zip_source_win32utf8.c" />
<ClCompile Include="libzip\zip_source_win32w.c" />
<ClCompile Include="libzip\zip_source_window.c" />
<ClCompile Include="libzip\zip_source_write.c" />
<ClCompile Include="libzip\zip_source_zip.c" />
@ -145,7 +146,9 @@
<ClInclude Include="libzip\zip.h" />
<ClInclude Include="libzip\zipconf.h" />
<ClInclude Include="libzip\zipint.h" />
<ClInclude Include="libzip\zipwin32.h" />
<ClInclude Include="libzip\zip_source_file.h" />
<ClInclude Include="libzip\zip_source_file_stdio.h" />
<ClInclude Include="libzip\zip_source_file_win32.h" />
<ClInclude Include="zlib\crc32.h" />
<ClInclude Include="zlib\deflate.h" />
<ClInclude Include="zlib\inffast.h" />

View File

@ -9,9 +9,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libzip\mkstemp.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_add.c">
<Filter>libzip</Filter>
</ClCompile>
@ -57,9 +54,6 @@
<ClCompile Include="libzip\zip_error_strerror.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_err_str.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_extra_field.c">
<Filter>libzip</Filter>
</ClCompile>
@ -207,15 +201,9 @@
<ClCompile Include="libzip\zip_source_crc.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_deflate.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_error.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_filep.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_free.c">
<Filter>libzip</Filter>
</ClCompile>
@ -231,9 +219,6 @@
<ClCompile Include="libzip\zip_source_open.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_pkware.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_read.c">
<Filter>libzip</Filter>
</ClCompile>
@ -261,18 +246,6 @@
<ClCompile Include="libzip\zip_source_tell_write.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_win32a.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_win32handle.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_win32utf8.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_win32w.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_window.c">
<Filter>libzip</Filter>
</ClCompile>
@ -357,10 +330,40 @@
<ClCompile Include="libzip\zip_algorithm_deflate.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_get_compression_flags.c">
<ClCompile Include="libzip\zip_source_accept_empty.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_accept_empty.c">
<ClCompile Include="libzip\zip_source_get_file_attributes.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_pkware_decode.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_pkware_encode.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_pkware.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_common.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_stdio.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_win32_named.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_win32_utf8.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_win32_utf16.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_source_file_win32.c">
<Filter>libzip</Filter>
</ClCompile>
<ClCompile Include="libzip\zip_err_str.c">
<Filter>libzip</Filter>
</ClCompile>
</ItemGroup>
@ -383,9 +386,6 @@
<ClInclude Include="libzip\zipint.h">
<Filter>libzip</Filter>
</ClInclude>
<ClInclude Include="libzip\zipwin32.h">
<Filter>libzip</Filter>
</ClInclude>
<ClInclude Include="zlib\crc32.h">
<Filter>zlib</Filter>
</ClInclude>
@ -416,5 +416,14 @@
<ClInclude Include="zlib\zutil.h">
<Filter>zlib</Filter>
</ClInclude>
<ClInclude Include="libzip\zip_source_file.h">
<Filter>libzip</Filter>
</ClInclude>
<ClInclude Include="libzip\zip_source_file_stdio.h">
<Filter>libzip</Filter>
</ClInclude>
<ClInclude Include="libzip\zip_source_file_win32.h">
<Filter>libzip</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
The authors can be contacted at <libzip@nih.at>

View File

@ -1,5 +1,52 @@
1.7.3 [2020-07-15]
==================
* Support cmake < 3.17 again.
* Fix pkgconfig file (regression in 1.7.2).
1.7.2 [2020-07-11]
==================
* Fixes for the CMake `find_project()` files.
* libzip moved to the CMake `libzip::` `NAMESPACE`.
* CMake usage best practice cleanups.
1.7.1 [2020-06-13]
==================
* Restore `LIBZIP_VERSION_{MAJOR,MINOR,MICRO}` symbols.
* Fixes warnings reported by PVS-Studio.
* Add `LIBZIP_DO_INSTALL` build setting to make it easier to use
libzip as subproject.
1.7.0 [2020-06-05]
==================
* Add support for encrypting using traditional PKWare encryption.
* Add `zip_compression_method_supported()`.
* Add `zip_encryption_method_supported()`.
* Add the `ZIP_SOURCE_GET_FILE_ATTRIBUTES` source command.
* Refactor stdio file backend.
* Add CMake find_project() support.
1.6.1 [2020-02-03]
==================
* Bugfix for double-free in `zipcmp(1)` during cleanup.
1.6.0 [2020-01-24]
==================
* Avoid using `umask()` since it's not thread-safe.
* Set close-on-exec flag when opening files.
* Do not accept empty files as valid zip archives any longer.
* Add support for XZ compressed files (using liblzma).
* Add support for cancelling while closing zip archives.
* Add support for setting the time in the on-disk format.
1.5.2 [2019-03-12]
==================
* Fix bug in AES encryption affecting certain file sizes
* Keep file permissions when modifying zip archives
* Support systems with small stack size.
@ -37,6 +84,7 @@
1.3.2 [2017-11-20]
==================
* Fix bug introduced in last: zip_t was erroneously freed if zip_close() failed.
1.3.1 [2017-11-19]
@ -181,7 +229,7 @@
0.9 [2008-07-25]
==================
* on Windows, explictly set dllimport/dllexport
* on Windows, explicitly set dllimport/dllexport
* remove erroneous references to GPL
* add support for torrentzip
* new functions: zip_get_archive_flag, zip_set_archive_flag

View File

@ -36,9 +36,7 @@
#include "zipconf.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* to have *_MAX definitions for all types when compiling with g++ */
#define __STDC_LIMIT_MACROS
@ -103,10 +101,6 @@ typedef char bool;
#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

View File

@ -76,7 +76,7 @@
#define HAVE_SHARED
/* END DEFINES */
#define PACKAGE "libzip"
#define VERSION "1.5.2"
#define VERSION "1.7.3"
#ifndef HAVE_SSIZE_T_LIBZIP
# if SIZE_T_LIBZIP == INT_LIBZIP

View File

@ -1,153 +0,0 @@
/* 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/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#include <process.h>
#else
#include <unistd.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
}

View File

@ -58,6 +58,9 @@ extern "C" {
#endif
#endif
#define _Nullable
#define _Nonnull
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
@ -161,8 +164,8 @@ extern "C" {
/* 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_TERSE 18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
#define ZIP_CM_LZMA2 33
#define ZIP_CM_XZ 95 /* XZ compressed data */
#define ZIP_CM_JPEG 96 /* Compressed Jpeg data */
@ -214,31 +217,32 @@ extern "C" {
enum zip_source_cmd {
ZIP_SOURCE_OPEN, /* prepare for reading */
ZIP_SOURCE_READ, /* read data */
ZIP_SOURCE_CLOSE, /* reading is done */
ZIP_SOURCE_STAT, /* get meta information */
ZIP_SOURCE_ERROR, /* get error information */
ZIP_SOURCE_FREE, /* cleanup and free resources */
ZIP_SOURCE_SEEK, /* set position for reading */
ZIP_SOURCE_TELL, /* get read position */
ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
ZIP_SOURCE_WRITE, /* write data */
ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
ZIP_SOURCE_TELL_WRITE, /* get write position */
ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
ZIP_SOURCE_REMOVE, /* remove file */
ZIP_SOURCE_GET_COMPRESSION_FLAGS, /* get compression flags, internal only */
ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
ZIP_SOURCE_ACCEPT_EMPTY /* whether empty files are valid archives */
ZIP_SOURCE_OPEN, /* prepare for reading */
ZIP_SOURCE_READ, /* read data */
ZIP_SOURCE_CLOSE, /* reading is done */
ZIP_SOURCE_STAT, /* get meta information */
ZIP_SOURCE_ERROR, /* get error information */
ZIP_SOURCE_FREE, /* cleanup and free resources */
ZIP_SOURCE_SEEK, /* set position for reading */
ZIP_SOURCE_TELL, /* get read position */
ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
ZIP_SOURCE_WRITE, /* write data */
ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
ZIP_SOURCE_TELL_WRITE, /* get write position */
ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
ZIP_SOURCE_REMOVE, /* remove file */
ZIP_SOURCE_RESERVED_1, /* previously used internally */
ZIP_SOURCE_BEGIN_WRITE_CLONING, /* like ZIP_SOURCE_BEGIN_WRITE, but keep part of original file */
ZIP_SOURCE_ACCEPT_EMPTY, /* whether empty files are valid archives */
ZIP_SOURCE_GET_FILE_ATTRIBUTES /* get additional file attributes */
};
typedef enum zip_source_cmd zip_source_cmd_t;
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (((zip_int64_t)1) << (cmd))
// clang-format off
/* clang-format off */
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
@ -261,7 +265,7 @@ typedef enum zip_source_cmd zip_source_cmd_t;
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
// clang-format on
/* clang-format on */
/* for use by sources */
struct zip_source_args_seek {
@ -276,9 +280,9 @@ typedef struct zip_source_args_seek zip_source_args_seek_t;
/* 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 */
int zip_err; /* libzip error code (ZIP_ER_*) */
int sys_err; /* copy of errno (E*) or zlib error code */
char *_Nullable str; /* string representation or NULL */
};
#define ZIP_STAT_NAME 0x0001u
@ -293,7 +297,7 @@ struct zip_error {
struct zip_stat {
zip_uint64_t valid; /* which fields have valid values */
const char * name; /* name of the file */
const char *_Nullable 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) */
@ -305,10 +309,27 @@ struct zip_stat {
};
struct zip_buffer_fragment {
zip_uint8_t * data;
zip_uint8_t *_Nonnull data;
zip_uint64_t length;
};
struct zip_file_attributes {
zip_uint64_t valid; /* which fields have valid values */
zip_uint8_t version; /* version of this struct, currently 1 */
zip_uint8_t host_system; /* host system on which file was created */
zip_uint8_t ascii; /* flag whether file is ASCII text */
zip_uint8_t version_needed; /* minimum version needed to extract file */
zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */
zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */
zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */
};
#define ZIP_FILE_ATTRIBUTES_HOST_SYSTEM 0x0001u
#define ZIP_FILE_ATTRIBUTES_ASCII 0x0002u
#define ZIP_FILE_ATTRIBUTES_VERSION_NEEDED 0x0004u
#define ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES 0x0008u
#define ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS 0x0010u
struct zip;
struct zip_file;
struct zip_source;
@ -316,121 +337,124 @@ 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_file_attributes zip_file_attributes_t;
typedef struct zip_source zip_source_t;
typedef struct zip_stat zip_stat_t;
typedef struct zip_buffer_fragment zip_buffer_fragment_t;
typedef zip_uint32_t zip_flags_t;
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
typedef void (*zip_progress_callback)(zip_t *, double, void *);
typedef int (*zip_cancel_callback)(zip_t *, void *);
typedef zip_int64_t (*zip_source_callback)(void *_Nullable, void *_Nullable, zip_uint64_t, zip_source_cmd_t);
typedef void (*zip_progress_callback)(zip_t *_Nonnull, double, void *_Nullable);
typedef int (*zip_cancel_callback)(zip_t *_Nonnull, void *_Nullable);
#ifndef ZIP_DISABLE_DEPRECATED
typedef void (*zip_progress_callback_t)(double);
ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t); /* use zip_register_progress_callback_with_state */
ZIP_EXTERN void zip_register_progress_callback(zip_t *_Nonnull, zip_progress_callback_t _Nullable); /* use zip_register_progress_callback_with_state */
ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */
ZIP_EXTERN const char * zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */
ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */
ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */
ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */
ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull); /* use zip_file_add */
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *_Nonnull, const char *_Nonnull); /* use zip_dir_add */
ZIP_EXTERN const char *_Nullable zip_get_file_comment(zip_t *_Nonnull, zip_uint64_t, int *_Nullable, int); /* use zip_file_get_comment */
ZIP_EXTERN int zip_get_num_files(zip_t *_Nonnull); /* use zip_get_num_entries instead */
ZIP_EXTERN int zip_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull); /* use zip_file_rename */
ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull); /* use zip_file_replace */
ZIP_EXTERN int zip_set_file_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, 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 *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
ZIP_EXTERN int zip_error_to_str(char *_Nonnull, zip_uint64_t, int, int); /* use zip_error_init_with_code / zip_error_strerror */
ZIP_EXTERN void zip_file_error_get(zip_file_t *_Nonnull, int *_Nullable, int *_Nullable); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
#endif
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 int zip_close(zip_t *_Nonnull);
ZIP_EXTERN int zip_delete(zip_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN void zip_discard(zip_t *_Nonnull);
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 zip_error_t *_Nonnull zip_get_error(zip_t *_Nonnull);
ZIP_EXTERN void zip_error_clear(zip_t *_Nonnull);
ZIP_EXTERN int zip_error_code_zip(const zip_error_t *_Nonnull);
ZIP_EXTERN int zip_error_code_system(const zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull);
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int);
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int);
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull);
ZIP_EXTERN int zip_error_system_type(const zip_error_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *_Nonnull, void *_Nonnull, 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_dostime(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_encryption(zip_t *, zip_uint64_t, zip_uint16_t, const char *);
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
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 zip_int8_t zip_fseek(zip_file_t *, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_ftell(zip_file_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 const char * zip_libzip_version(void);
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
ZIP_EXTERN zip_t * zip_open(const char *, int, int *);
ZIP_EXTERN zip_t * zip_open_from_source(zip_source_t *, int, zip_error_t *);
ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *, double, zip_progress_callback, void (*)(void *), void *);
ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *, zip_cancel_callback, void (*)(void *), void *);
ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
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 int zip_source_begin_write_cloning(zip_source_t *, zip_uint64_t);
ZIP_EXTERN zip_source_t * zip_source_buffer(zip_t *, const void *, zip_uint64_t, int);
ZIP_EXTERN zip_source_t * zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *);
ZIP_EXTERN zip_source_t * zip_source_buffer_fragment(zip_t *, const zip_buffer_fragment_t *, zip_uint64_t, int);
ZIP_EXTERN zip_source_t * zip_source_buffer_fragment_create(const zip_buffer_fragment_t *, zip_uint64_t, int, zip_error_t *);
ZIP_EXTERN int zip_source_close(zip_source_t *);
ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
ZIP_EXTERN zip_error_t * zip_source_error(zip_source_t *);
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 int zip_fclose(zip_file_t *_Nonnull);
ZIP_EXTERN zip_t *_Nullable zip_fdopen(int, int, int *_Nullable);
ZIP_EXTERN zip_int64_t zip_file_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull, zip_flags_t);
ZIP_EXTERN void zip_file_attributes_init(zip_file_attributes_t *_Nonnull);
ZIP_EXTERN void zip_file_error_clear(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_extra_field_delete(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_extra_field_set(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *_Nullable, zip_uint16_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t);
ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get_by_id(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_flags_t);
ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t);
ZIP_EXTERN zip_error_t *_Nonnull zip_file_get_error(zip_file_t *_Nonnull);
ZIP_EXTERN int zip_file_get_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t *_Nullable, zip_uint32_t *_Nullable);
ZIP_EXTERN int zip_file_rename(zip_t *_Nonnull, zip_uint64_t, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull, zip_flags_t);
ZIP_EXTERN int zip_file_set_comment(zip_t *_Nonnull, zip_uint64_t, const char *_Nullable, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_dostime(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
ZIP_EXTERN int zip_file_set_encryption(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, const char *_Nullable);
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
ZIP_EXTERN int zip_file_set_mtime(zip_t *_Nonnull, zip_uint64_t, time_t, zip_flags_t);
ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_encrypted(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, const char *_Nullable);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index_encrypted(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, const char *_Nullable);
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_int8_t zip_fseek(zip_file_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_ftell(zip_file_t *_Nonnull);
ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t);
ZIP_EXTERN int zip_get_archive_flag(zip_t *_Nonnull, zip_flags_t, zip_flags_t);
ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t);
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t);
ZIP_EXTERN const char *_Nonnull zip_libzip_version(void);
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t);
ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable);
ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable);
ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *_Nonnull, double, zip_progress_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
ZIP_EXTERN int zip_register_cancel_callback_with_state(zip_t *_Nonnull, zip_cancel_callback _Nullable, void (*_Nullable)(void *_Nullable), void *_Nullable);
ZIP_EXTERN int zip_set_archive_comment(zip_t *_Nonnull, const char *_Nullable, zip_uint16_t);
ZIP_EXTERN int zip_set_archive_flag(zip_t *_Nonnull, zip_flags_t, int);
ZIP_EXTERN int zip_set_default_password(zip_t *_Nonnull, const char *_Nullable);
ZIP_EXTERN int zip_set_file_compression(zip_t *_Nonnull, zip_uint64_t, zip_int32_t, zip_uint32_t);
ZIP_EXTERN int zip_source_begin_write(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_begin_write_cloning(zip_source_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer(zip_t *_Nonnull, const void *_Nullable, zip_uint64_t, int);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment(zip_t *_Nonnull, const zip_buffer_fragment_t *_Nonnull, zip_uint64_t, int);
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_fragment_create(const zip_buffer_fragment_t *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_commit_write(zip_source_t *_Nonnull);
ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull);
ZIP_EXTERN zip_source_t *_Nullable zip_source_file(zip_t *_Nonnull, const char *_Nonnull, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_file_create(const char *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_filep(zip_t *_Nonnull, FILE *_Nonnull, zip_uint64_t, zip_int64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_filep_create(FILE *_Nonnull, zip_uint64_t, zip_int64_t, zip_error_t *_Nullable);
ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_function(zip_t *_Nonnull, zip_source_callback _Nonnull, void *_Nullable);
ZIP_EXTERN zip_source_t *_Nullable zip_source_function_create(zip_source_callback _Nonnull, void *_Nullable, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_get_file_attributes(zip_source_t *_Nonnull, zip_file_attributes_t *_Nonnull);
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull);
ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull);
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 *);
ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t);
ZIP_EXTERN void zip_source_rollback_write(zip_source_t *_Nonnull);
ZIP_EXTERN int zip_source_seek(zip_source_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *_Nonnull, zip_uint64_t, zip_error_t *_Nullable);
ZIP_EXTERN int zip_source_seek_write(zip_source_t *_Nonnull, zip_int64_t, int);
ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *_Nonnull);
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *_Nonnull);
#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 *);
@ -439,15 +463,17 @@ ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip
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 *);
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *_Nonnull, const void *_Nullable, zip_uint64_t);
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
ZIP_EXTERN int zip_stat(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull);
ZIP_EXTERN void zip_stat_init(zip_stat_t *_Nonnull);
ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull);
ZIP_EXTERN int zip_unchange(zip_t *_Nonnull, zip_uint64_t);
ZIP_EXTERN int zip_unchange_all(zip_t *_Nonnull);
ZIP_EXTERN int zip_unchange_archive(zip_t *_Nonnull);
ZIP_EXTERN int zip_compression_method_supported(zip_int32_t method, int compress);
ZIP_EXTERN int zip_encryption_method_supported(zip_uint16_t method, int encode);
#ifdef __cplusplus
}

View File

@ -91,8 +91,8 @@ deallocate(void *ud) {
}
static int
compression_flags(void *ud) {
static zip_uint16_t
general_purpose_bit_flags(void *ud) {
struct ctx *ctx = (struct ctx *)ud;
if (!ctx->compress) {
@ -100,10 +100,10 @@ compression_flags(void *ud) {
}
if (ctx->compression_flags < 3) {
return 2;
return 2 << 1;
}
else if (ctx->compression_flags > 7) {
return 1;
return 1 << 1;
}
return 0;
}
@ -220,12 +220,13 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
}
}
// clang-format off
/* clang-format off */
zip_compression_algorithm_t zip_algorithm_deflate_compress = {
compress_allocate,
deallocate,
compression_flags,
general_purpose_bit_flags,
20,
start,
end,
input,
@ -237,7 +238,8 @@ zip_compression_algorithm_t zip_algorithm_deflate_compress = {
zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
decompress_allocate,
deallocate,
compression_flags,
general_purpose_bit_flags,
20,
start,
end,
input,
@ -245,4 +247,4 @@ zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
process
};
// clang-format on
/* clang-format on */

View File

@ -36,25 +36,17 @@
#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/stat.h>
#include <sys/types.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);
ZIP_EXTERN int
zip_close(zip_t *za) {
@ -204,6 +196,7 @@ zip_close(zip_t *za) {
}
if ((off = zip_source_tell_write(za->src)) < 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
@ -221,7 +214,7 @@ zip_close(zip_t *za) {
}
/* add_data writes dirent */
if (add_data(za, zs ? zs : entry->source, de) < 0) {
if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) {
error = 1;
if (zs)
zip_source_free(zs);
@ -233,8 +226,11 @@ zip_close(zip_t *za) {
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 (de->encryption_method != ZIP_EM_TRAD_PKWARE) {
/* when copying data, all sizes are known -> no data descriptor needed */
/* except for PKWare encryption, where removing the data descriptor breaks password validation */
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
}
if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
error = 1;
break;
@ -245,13 +241,20 @@ zip_close(zip_t *za) {
}
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
_zip_error_set_from_source(&za->error, za->src);
error = 1;
error = 1;
break;
}
if (copy_data(za, de->comp_size) < 0) {
error = 1;
error = 1;
break;
}
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) {
error = 1;
break;
}
}
}
}
@ -282,14 +285,14 @@ zip_close(zip_t *za) {
static int
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_int64_t offstart, offdata, offend, data_length;
struct zip_stat st;
zip_stat_t st;
zip_file_attributes_t attributes;
zip_source_t *src_final, *src_tmp;
int ret;
int is_zip64;
zip_flags_t flags;
zip_int8_t compression_flags;
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
if (zip_source_stat(src, &st) < 0) {
@ -453,6 +456,9 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
zip_source_free(src_final);
return -1;
}
if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
}
zip_source_free(src_final);
src_final = src_tmp;
@ -471,7 +477,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
ret = -1;
}
if ((compression_flags = zip_source_get_compression_flags(src_final)) < 0) {
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
_zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
@ -507,8 +513,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
de->crc = st.crc;
de->uncomp_size = st.size;
de->comp_size = (zip_uint64_t)(offend - offdata);
de->bitflags = (zip_uint16_t)((de->bitflags & (zip_uint16_t)~6) | ((zip_uint8_t)compression_flags << 1));
_zip_dirent_set_version_needed(de, (flags & ZIP_FL_FORCE_ZIP64) != 0);
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
return -1;
@ -524,6 +529,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de) {
return -1;
}
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
if (write_data_descriptor(za, de, is_zip64) < 0) {
return -1;
}
}
return 0;
}
@ -656,3 +667,37 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
return changed;
}
static int
write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH);
int ret = 0;
if (buffer == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return -1;
}
_zip_buffer_put(buffer, DATADES_MAGIC, 4);
_zip_buffer_put_32(buffer, de->crc);
if (is_zip64) {
_zip_buffer_put_64(buffer, de->comp_size);
_zip_buffer_put_64(buffer, de->uncomp_size);
}
else {
_zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
_zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
}
if (!_zip_buffer_ok(buffer)) {
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
ret = -1;
}
else {
ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer));
}
_zip_buffer_free(buffer);
return ret;
}

View File

@ -35,7 +35,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
@ -522,29 +521,54 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
return -1;
}
if (zde->uncomp_size == ZIP_UINT32_MAX)
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)
if (zde->comp_size == ZIP_UINT32_MAX) {
zde->comp_size = _zip_buffer_get_64(ef_buffer);
}
if (!local) {
if (zde->offset == ZIP_UINT32_MAX)
if (zde->offset == ZIP_UINT32_MAX) {
zde->offset = _zip_buffer_get_64(ef_buffer);
if (zde->disk_number == ZIP_UINT16_MAX)
}
if (zde->disk_number == ZIP_UINT16_MAX) {
zde->disk_number = _zip_buffer_get_32(ef_buffer);
}
}
if (!_zip_buffer_eof(ef_buffer)) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(ef_buffer);
if (!from_buffer) {
_zip_buffer_free(buffer);
/* accept additional fields if values match */
bool ok = true;
switch (got_len) {
case 28:
_zip_buffer_set_offset(ef_buffer, 24);
if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
ok = false;
}
/* fallthrough */
case 24:
_zip_buffer_set_offset(ef_buffer, 0);
if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
ok = false;
}
break;
default:
ok = false;
}
if (!ok) {
zip_error_set(error, ZIP_ER_INCONS, 0);
_zip_buffer_free(ef_buffer);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
return -1;
}
_zip_buffer_free(ef_buffer);
}
@ -572,7 +596,7 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
return (zip_int64_t)(size + variable_size);
return (zip_int64_t)size + (zip_int64_t)variable_size;
}
@ -867,9 +891,9 @@ _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
_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, de->version_madeby);
}
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
_zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, de->version_needed));
_zip_buffer_put_16(buffer, de->bitflags);
if (is_winzip_aes) {
_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
@ -1074,7 +1098,7 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
tpm = localtime(&intime);
#endif
if (tpm == NULL) {
/* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */
/* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */
*ddate = (1 << 5) + 1;
*dtime = 0;
return;
@ -1091,36 +1115,49 @@ _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
void
_zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) {
_zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) {
zip_uint16_t length;
if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
}
if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) {
de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
}
/* manually set attributes are preferred over attributes provided by source */
if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) {
de->ext_attrib = attributes->external_file_attributes;
}
if (de->comp_method == ZIP_CM_LZMA) {
de->version_needed = 63;
return;
}
if (de->comp_method == ZIP_CM_BZIP2) {
else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) {
de->version_needed = 51;
}
else if (de->comp_method == ZIP_CM_BZIP2) {
de->version_needed = 46;
return;
}
if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
de->version_needed = 45;
return;
}
if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
de->version_needed = 20;
return;
}
else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') {
de->version_needed = 20;
}
else {
de->version_needed = 10;
}
/* directory */
if ((length = _zip_string_length(de->filename)) > 0) {
if (de->filename->raw[length - 1] == '/') {
de->version_needed = 20;
return;
}
if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed);
}
de->version_needed = 10;
de->version_madeby = 63 | (de->version_madeby & 0xff00);
if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
}
}

View File

@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "zipint.h"

View File

@ -33,8 +33,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"

View File

@ -33,10 +33,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "zipint.h"

View File

@ -32,9 +32,6 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include "zipint.h"

View File

@ -39,10 +39,7 @@ zip_encryption_implementation
_zip_get_encryption_implementation(zip_uint16_t em, int operation) {
switch (em) {
case ZIP_EM_TRAD_PKWARE:
if (operation == ZIP_CODEC_ENCODE) {
return NULL;
}
return zip_source_pkware;
return operation == ZIP_CODEC_DECODE ? zip_source_pkware_decode : zip_source_pkware_encode;
#if defined(HAVE_CRYPTO)
case ZIP_EM_AES_128:
@ -55,3 +52,11 @@ _zip_get_encryption_implementation(zip_uint16_t em, int operation) {
return NULL;
}
}
ZIP_EXTERN int
zip_encryption_method_supported(zip_uint16_t method, int encode) {
if (method == ZIP_EM_NONE) {
return 1;
}
return _zip_get_encryption_implementation(method, encode ? ZIP_CODEC_ENCODE : ZIP_CODEC_DECODE) != NULL;
}

View File

@ -32,19 +32,13 @@
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "zipint.h"
typedef enum {
EXISTS_ERROR = -1,
EXISTS_NOT = 0,
EXISTS_OK
} exists_t;
typedef enum { EXISTS_ERROR = -1, EXISTS_NOT = 0, EXISTS_OK } exists_t;
static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);

View File

@ -0,0 +1,112 @@
/*
zip_pkware.c -- Traditional PKWARE de/encryption backend routines
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 <zlib.h>
#include "zipint.h"
#define PKWARE_KEY0 305419896
#define PKWARE_KEY1 591751049
#define PKWARE_KEY2 878082192
static void
update_keys(zip_pkware_keys_t *keys, zip_uint8_t b) {
keys->key[0] = (zip_uint32_t)crc32(keys->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
keys->key[1] = (keys->key[1] + (keys->key[0] & 0xff)) * 134775813 + 1;
b = (zip_uint8_t)(keys->key[1] >> 24);
keys->key[2] = (zip_uint32_t)crc32(keys->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
}
static zip_uint8_t
crypt_byte(zip_pkware_keys_t *keys) {
zip_uint16_t tmp;
tmp = (zip_uint16_t)(keys->key[2] | 2);
tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
return (zip_uint8_t)tmp;
}
void
_zip_pkware_keys_reset(zip_pkware_keys_t *keys) {
keys->key[0] = PKWARE_KEY0;
keys->key[1] = PKWARE_KEY1;
keys->key[2] = PKWARE_KEY2;
}
void
_zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) {
zip_uint64_t i;
zip_uint8_t b;
zip_uint8_t tmp;
for (i = 0; i < len; i++) {
b = in[i];
if (out != NULL) {
tmp = crypt_byte(keys);
update_keys(keys, b);
b ^= tmp;
out[i] = b;
}
else {
/* during initialization, we're only interested in key updates */
update_keys(keys, b);
}
}
}
void
_zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len) {
zip_uint64_t i;
zip_uint8_t b;
zip_uint8_t tmp;
for (i = 0; i < len; i++) {
b = in[i];
/* during initialization, we're only interested in key updates */
if (out != NULL) {
tmp = crypt_byte(keys);
b ^= tmp;
out[i] = b;
}
update_keys(keys, b);
}
}

View File

@ -209,10 +209,8 @@ _zip_progress_update(zip_progress_t *progress, double sub_current) {
ZIP_EXTERN int
zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
zip_progress_t *progress = NULL;
if (callback != NULL) {
if (za->progress == NULL) {
if (za->progress == NULL) {
if ((za->progress = _zip_progress_new(za)) == NULL) {
return -1;
}
@ -238,10 +236,8 @@ zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progr
ZIP_EXTERN int
zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
zip_progress_t *progress = NULL;
if (callback != NULL) {
if (za->progress == NULL) {
if (za->progress == NULL) {
if ((za->progress = _zip_progress_new(za)) == NULL) {
return -1;
}

View File

@ -32,8 +32,6 @@
*/
#include <string.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"

View File

@ -32,8 +32,6 @@
*/
#include <stdlib.h>
#define _ZIP_COMPILING_DEPRECATED
#include "zipint.h"

View File

@ -61,6 +61,7 @@ typedef struct buffer buffer_t;
struct read_data {
zip_error_t error;
time_t mtime;
zip_file_attributes_t attributes;
buffer_t *in;
buffer_t *out;
};
@ -79,33 +80,42 @@ static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_u
static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t);
zip_source_t *zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error);
zip_source_t *zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error);
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);
return zip_source_buffer_with_attributes_create(data, len, freep, NULL, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) {
return zip_source_buffer_with_attributes_create(data, len, freep, NULL, error);
}
zip_source_t *
zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error) {
zip_buffer_fragment_t fragment;
if (data == NULL) {
if (len > 0) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (len > 0) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
return zip_source_buffer_fragment_create(NULL, 0, freep, error);
return zip_source_buffer_fragment_with_attributes_create(NULL, 0, freep, attributes, error);
}
fragment.data = (zip_uint8_t *)data;
fragment.length = len;
return zip_source_buffer_fragment_create(&fragment, 1, freep, error);
return zip_source_buffer_fragment_with_attributes_create(&fragment, 1, freep, attributes, error);
}
@ -115,12 +125,17 @@ zip_source_buffer_fragment(zip_t *za, const zip_buffer_fragment_t *fragments, zi
return NULL;
}
return zip_source_buffer_fragment_create(fragments, nfragments, freep, &za->error);
return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, &za->error);
}
ZIP_EXTERN zip_source_t *
zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_error_t *error) {
return zip_source_buffer_fragment_with_attributes_create(fragments, nfragments, freep, NULL, error);
}
zip_source_t *
zip_source_buffer_fragment_with_attributes_create(const zip_buffer_fragment_t *fragments, zip_uint64_t nfragments, int freep, zip_file_attributes_t *attributes, zip_error_t *error) {
struct read_data *ctx;
zip_source_t *zs;
buffer_t *buffer;
@ -143,6 +158,12 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui
ctx->in = buffer;
ctx->out = NULL;
ctx->mtime = time(NULL);
if (attributes) {
memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
}
else {
zip_file_attributes_init(&ctx->attributes);
}
zip_error_init(&ctx->error);
if ((zs = zip_source_function_create(read_data, ctx, error)) == NULL) {
@ -155,6 +176,11 @@ zip_source_buffer_fragment_create(const zip_buffer_fragment_t *fragments, zip_ui
}
zip_source_t *
zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes) {
return zip_source_buffer_with_attributes_create(data, len, freep, attributes, &za->error);
}
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;
@ -194,6 +220,17 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
free(ctx);
return 0;
case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
if (len < sizeof(ctx->attributes)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
return sizeof(ctx->attributes);
}
case ZIP_SOURCE_OPEN:
ctx->in->offset = 0;
ctx->in->current_fragment = 0;
@ -250,7 +287,7 @@ read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
}
case ZIP_SOURCE_SUPPORTS:
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
return zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_BEGIN_WRITE_CLONING, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
case ZIP_SOURCE_TELL:
if (ctx->in->offset > ZIP_INT64_MAX) {

View File

@ -31,7 +31,6 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@ -68,12 +67,12 @@ static struct implementation implementations[] = {
{ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress},
#endif
#if defined(HAVE_LIBLZMA)
/* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2
archives made this way - and vice versa.
/* Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2
archives made this way - and vice versa.
{ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
{ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
*/
{ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
{ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
*/
{ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
#endif
@ -106,10 +105,10 @@ get_algorithm(zip_int32_t method, bool compress) {
return NULL;
}
bool
zip_compression_method_supported(zip_int32_t method, bool compress) {
ZIP_EXTERN int
zip_compression_method_supported(zip_int32_t method, int compress) {
if (method == ZIP_CM_STORE) {
return true;
return 1;
}
return get_algorithm(method, compress) != NULL;
}
@ -357,9 +356,6 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
}
return 0;
case ZIP_SOURCE_GET_COMPRESSION_FLAGS:
return ctx->is_stored ? 0 : ctx->algorithm->compression_flags(ctx->ud);
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, len);
@ -367,8 +363,24 @@ compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip
context_free(ctx);
return 0;
case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;
if (len < sizeof(*attributes)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
attributes->version_needed = ctx->algorithm->version_needed;
attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
attributes->general_purpose_bit_flags = (ctx->is_stored ? 0 : ctx->algorithm->general_purpose_bit_flags(ctx->ud));
return sizeof(*attributes);
}
case ZIP_SOURCE_SUPPORTS:
return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1);
return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
default:
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);

View File

@ -34,7 +34,7 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "zipint.h"
@ -167,7 +167,7 @@ crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source
return -1;
}
return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1);
return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
}
case ZIP_SOURCE_SEEK: {

View File

@ -1,415 +0,0 @@
/*
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);
}

View File

@ -1,61 +0,0 @@
/*
zip_source_file.c -- create data source from file
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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);
}

View File

@ -0,0 +1,90 @@
/*
zip_source_file.h -- header for common file operations
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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.
*/
struct zip_source_file_stat {
zip_uint64_t size; /* must be valid for regular files */
time_t mtime; /* must always be valid, is initialized to current time */
bool exists; /* must always be vaild */
bool regular_file; /* must always be valid */
};
typedef struct zip_source_file_context zip_source_file_context_t;
typedef struct zip_source_file_operations zip_source_file_operations_t;
typedef struct zip_source_file_stat zip_source_file_stat_t;
struct zip_source_file_context {
zip_error_t error; /* last error information */
zip_int64_t supports;
/* reading */
char *fname; /* name of file to read from */
void *f; /* file to read from */
zip_stat_t st; /* stat information passed in */
zip_file_attributes_t attributes; /* additional file attributes */
zip_error_t stat_error; /* error returned for stat */
zip_uint64_t start; /* start offset of data to read */
zip_uint64_t len; /* length of the file, 0 for up to EOF */
zip_uint64_t offset; /* current offset relative to start (0 is beginning of part we read) */
/* writing */
char *tmpname;
void *fout;
zip_source_file_operations_t *ops;
void *ops_userdata;
};
/* The following methods must be implemented to support each feature:
- close, read, seek, and stat must always be implemented.
- To support specifying the file by name, open, and strdup must be implemented.
- For write support, the file must be specified by name and close, commit_write, create_temp_output, remove, rollback_write, and tell must be implemented.
- create_temp_output_cloning is always optional. */
struct zip_source_file_operations {
void (*close)(zip_source_file_context_t *ctx);
zip_int64_t (*commit_write)(zip_source_file_context_t *ctx);
zip_int64_t (*create_temp_output)(zip_source_file_context_t *ctx);
zip_int64_t (*create_temp_output_cloning)(zip_source_file_context_t *ctx, zip_uint64_t len);
bool (*open)(zip_source_file_context_t *ctx);
zip_int64_t (*read)(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
zip_int64_t (*remove)(zip_source_file_context_t *ctx);
void (*rollback_write)(zip_source_file_context_t *ctx);
bool (*seek)(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
bool (*stat)(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
char *(*string_duplicate)(zip_source_file_context_t *ctx, const char *);
zip_int64_t (*tell)(zip_source_file_context_t *ctx, void *f);
zip_int64_t (*write)(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
};
zip_source_t *zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error);

View File

@ -0,0 +1,378 @@
/*
zip_source_file_common.c -- create data source from file
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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"
#include "zip_source_file.h"
static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
static void
zip_source_file_stat_init(zip_source_file_stat_t *st) {
st->size = 0;
st->mtime = time(NULL);
st->exists = false;
st->regular_file = false;
}
zip_source_t *
zip_source_file_common_new(const char *fname, void *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_source_file_operations_t *ops, void *ops_userdata, zip_error_t *error) {
zip_source_file_context_t *ctx;
zip_source_t *zs;
zip_source_file_stat_t sb;
if (ops == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (ops->close == NULL || ops->read == NULL || ops->seek == NULL || ops->stat == NULL) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
if (ops->write != NULL && (ops->commit_write == NULL || ops->create_temp_output == NULL || ops->remove == NULL || ops->rollback_write == NULL || ops->tell == NULL)) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
if (fname != NULL) {
if (ops->open == NULL || ops->string_duplicate == NULL) {
zip_error_set(error, ZIP_ER_INTERNAL, 0);
return NULL;
}
}
else if (file == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (len < 0) {
len = 0;
}
if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx = (zip_source_file_context_t *)malloc(sizeof(zip_source_file_context_t))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
ctx->ops = ops;
ctx->ops_userdata = ops_userdata;
ctx->fname = NULL;
if (fname) {
if ((ctx->fname = ops->string_duplicate(ctx, fname)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
}
ctx->f = file;
ctx->start = start;
ctx->len = (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);
}
if (ctx->len > 0) {
ctx->st.size = ctx->len;
ctx->st.valid |= ZIP_STAT_SIZE;
}
zip_error_init(&ctx->stat_error);
ctx->tmpname = NULL;
ctx->fout = NULL;
zip_error_init(&ctx->error);
zip_file_attributes_init(&ctx->attributes);
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
zip_source_file_stat_init(&sb);
if (!ops->stat(ctx, &sb)) {
_zip_error_copy(error, &ctx->error);
free(ctx->fname);
free(ctx);
return NULL;
}
if (!sb.exists) {
if (ctx->fname && ctx->start == 0 && ctx->len == 0 && ops->write != NULL) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
/* zip_open_from_source checks for this to detect non-existing files */
zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
}
else {
zip_error_set(&ctx->stat_error, ZIP_ER_READ, ENOENT);
free(ctx->fname);
free(ctx);
return NULL;
}
}
else {
if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
ctx->st.mtime = sb.mtime;
ctx->st.valid |= ZIP_STAT_MTIME;
}
if (sb.regular_file) {
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
if (ctx->start + ctx->len > sb.size) {
zip_error_set(error, ZIP_ER_INVAL, 0);
free(ctx->fname);
free(ctx);
return NULL;
}
if (ctx->len == 0) {
ctx->len = sb.size - ctx->start;
ctx->st.size = ctx->len;
ctx->st.valid |= ZIP_STAT_SIZE;
/* when using a partial file, don't allow writing */
if (ctx->fname && start == 0 && ops->write != NULL) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
}
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES);
}
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY);
if (ops->create_temp_output_cloning != NULL) {
if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) {
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING);
}
}
if ((zs = zip_source_function_create(read_file, ctx, error)) == NULL) {
free(ctx->fname);
free(ctx);
return NULL;
}
return zs;
}
static zip_int64_t
read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
zip_source_file_context_t *ctx;
char *buf;
ctx = (zip_source_file_context_t *)state;
buf = (char *)data;
switch (cmd) {
case ZIP_SOURCE_ACCEPT_EMPTY:
return 0;
case ZIP_SOURCE_BEGIN_WRITE:
/* write support should not be set if fname is NULL */
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
return -1;
}
return ctx->ops->create_temp_output(ctx);
case ZIP_SOURCE_BEGIN_WRITE_CLONING:
/* write support should not be set if fname is NULL */
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
return -1;
}
return ctx->ops->create_temp_output_cloning(ctx, len);
case ZIP_SOURCE_CLOSE:
if (ctx->fname) {
ctx->ops->close(ctx);
ctx->f = NULL;
}
return 0;
case ZIP_SOURCE_COMMIT_WRITE: {
zip_int64_t ret = ctx->ops->commit_write(ctx);
ctx->fout = NULL;
if (ret == 0) {
free(ctx->tmpname);
ctx->tmpname = NULL;
}
return ret;
}
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) {
ctx->ops->close(ctx);
}
free(ctx);
return 0;
case ZIP_SOURCE_GET_FILE_ATTRIBUTES:
if (len < sizeof(ctx->attributes)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
return sizeof(ctx->attributes);
case ZIP_SOURCE_OPEN:
if (ctx->fname) {
if (ctx->ops->open(ctx) == false) {
return -1;
}
}
if (ctx->start > 0) { // TODO: rewind on re-open
if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)ctx->start, SEEK_SET) == false) {
/* TODO: skip by reading */
return -1;
}
}
ctx->offset = 0;
return 0;
case ZIP_SOURCE_READ: {
zip_int64_t i;
zip_uint64_t n;
if (ctx->len > 0) {
n = ZIP_MIN(ctx->len - ctx->offset, len);
}
else {
n = len;
}
if ((i = ctx->ops->read(ctx, buf, n)) < 0) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
ctx->offset += (zip_uint64_t)i;
return i;
}
case ZIP_SOURCE_REMOVE:
return ctx->ops->remove(ctx);
case ZIP_SOURCE_ROLLBACK_WRITE:
ctx->ops->rollback_write(ctx);
ctx->fout = NULL;
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
case ZIP_SOURCE_SEEK: {
zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset, ctx->len, data, len, &ctx->error);
if (new_offset < 0) {
return -1;
}
/* The actual offset inside the file must be representable as zip_int64_t. */
if (new_offset > ZIP_INT64_MAX - (zip_int64_t)ctx->start) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW);
return -1;
}
ctx->offset = (zip_uint64_t)new_offset;
if (ctx->ops->seek(ctx, ctx->f, (zip_int64_t)(ctx->offset + ctx->start), SEEK_SET) == false) {
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 (ctx->ops->seek(ctx, ctx->fout, args->offset, args->whence) == false) {
return -1;
}
return 0;
}
case ZIP_SOURCE_STAT: {
if (len < sizeof(ctx->st))
return -1;
if (zip_error_code_zip(&ctx->stat_error) != 0) {
zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
return -1;
}
memcpy(data, &ctx->st, sizeof(ctx->st));
return sizeof(ctx->st);
}
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;
case ZIP_SOURCE_TELL:
return (zip_int64_t)ctx->offset;
case ZIP_SOURCE_TELL_WRITE:
return ctx->ops->tell(ctx, ctx->fout);
case ZIP_SOURCE_WRITE:
return ctx->ops->write(ctx, data, len);
default:
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
}

View File

@ -0,0 +1,208 @@
/*
zip_source_file_stdio.c -- read-only stdio file source implementation
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 "zip_source_file.h"
#include "zip_source_file_stdio.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifdef _WIN32
#ifndef S_IWUSR
#define S_IWUSR _S_IWRITE
#endif
#endif
/* clang-format off */
static zip_source_file_operations_t ops_stdio_read = {
_zip_stdio_op_close,
NULL,
NULL,
NULL,
NULL,
_zip_stdio_op_read,
NULL,
NULL,
_zip_stdio_op_seek,
_zip_stdio_op_stat,
NULL,
_zip_stdio_op_tell,
NULL
};
/* clang-format on */
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_common_new(NULL, file, start, length, NULL, &ops_stdio_read, NULL, error);
}
void
_zip_stdio_op_close(zip_source_file_context_t *ctx) {
fclose((FILE *)ctx->f);
}
zip_int64_t
_zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
size_t i;
if (len > SIZE_MAX) {
len = SIZE_MAX;
}
if ((i = fread(buf, 1, (size_t)len, ctx->f)) == 0) {
if (ferror((FILE *)ctx->f)) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
}
return (zip_int64_t)i;
}
bool
_zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) {
#if ZIP_FSEEK_MAX > ZIP_INT64_MAX
if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, EOVERFLOW);
return false;
}
#endif
if (fseeko((FILE *)f, (off_t)offset, whence) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return false;
}
return true;
}
bool
_zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
struct stat sb;
int ret;
if (ctx->fname) {
ret = stat(ctx->fname, &sb);
}
else {
ret = fstat(fileno((FILE *)ctx->f), &sb);
}
if (ret < 0) {
if (errno == ENOENT) {
st->exists = false;
return true;
}
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return false;
}
st->size = (zip_uint64_t)sb.st_size;
st->mtime = sb.st_mtime;
st->regular_file = S_ISREG(sb.st_mode);
st->exists = true;
/* We're using UNIX file API, even on Windows; thus, we supply external file attributes with Unix values. */
/* TODO: This could be improved on Windows by providing Windows-specific file attributes */
ctx->attributes.valid = ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES;
ctx->attributes.host_system = ZIP_OPSYS_UNIX;
ctx->attributes.external_file_attributes = (((zip_uint32_t)sb.st_mode) << 16) | ((sb.st_mode & S_IWUSR) ? 0 : 1);
return true;
}
zip_int64_t
_zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) {
off_t offset = ftello((FILE *)f);
if (offset < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
}
return offset;
}
/*
* fopen replacement that sets the close-on-exec flag
* some implementations support an fopen 'e' flag for that,
* but e.g. macOS doesn't.
*/
FILE *
_zip_fopen_close_on_exec(const char *name, bool writeable) {
int fd;
int flags;
FILE *fp;
flags = O_CLOEXEC;
if (writeable) {
flags |= O_RDWR;
}
else {
flags |= O_RDONLY;
}
/* mode argument needed on Windows */
if ((fd = open(name, flags, 0666)) < 0) {
return NULL;
}
if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) {
return NULL;
}
return fp;
}

View File

@ -1,6 +1,9 @@
#ifndef _HAD_ZIP_SOURCE_FILE_STDIO_H
#define _HAD_ZIP_SOURCE_FILE_STDIO_H
/*
zip_source_get_compression_flags.c -- get compression flags for entry
Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner
zip_source_file_stdio.h -- common header for stdio file implementation
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -31,27 +34,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "zipint.h"
void _zip_stdio_op_close(zip_source_file_context_t *ctx);
zip_int64_t _zip_stdio_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
bool _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f);
#define ZIP_COMPRESSION_BITFLAG_MAX 3
FILE *_zip_fopen_close_on_exec(const char *name, bool writeable);
zip_int8_t
zip_source_get_compression_flags(zip_source_t *src) {
while (src) {
if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_COMPRESSION_FLAGS))) {
zip_int64_t ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_GET_COMPRESSION_FLAGS);
if (ret < 0) {
return -1;
}
if (ret > ZIP_COMPRESSION_BITFLAG_MAX) {
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
return -1;
}
return (zip_int8_t)ret;
}
src = src->src;
}
return 0;
}
#endif /* _HAD_ZIP_SOURCE_FILE_STDIO_H */

View File

@ -0,0 +1,230 @@
/*
zip_source_file_win32.c -- read-only Windows file source implementation
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 "zip_source_file_win32.h"
static bool _zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
static bool _zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h);
static zip_source_file_operations_t ops_win32_read = {
_zip_win32_op_close,
NULL,
NULL,
NULL,
NULL,
_zip_win32_op_read,
NULL,
NULL,
_zip_win32_op_seek,
_zip_win32_op_stat,
NULL,
_zip_win32_op_tell,
NULL
};
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_file_common_new(NULL, h, start, length, NULL, &ops_win32_read, NULL, error);
}
void
_zip_win32_op_close(zip_source_file_context_t *ctx) {
CloseHandle((HANDLE)ctx->f);
}
zip_int64_t
_zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len) {
DWORD i;
/* TODO: cap len to "DWORD_MAX" */
if (!ReadFile((HANDLE)ctx->f, buf, (DWORD)len, &i, NULL)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return (zip_int64_t)i;
}
bool
_zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence) {
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(&ctx->error, ZIP_ER_SEEK, EINVAL);
return -1;
}
li.QuadPart = (LONGLONG)offset;
if (!SetFilePointerEx((HANDLE)f, li, NULL, method)) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
return false;
}
return true;
}
static bool
_zip_win32_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
return _zip_stat_win32(ctx, st, (HANDLE)ctx->f);
}
zip_int64_t
_zip_win32_op_tell(zip_source_file_context_t *ctx, void *f) {
LARGE_INTEGER zero;
LARGE_INTEGER new_offset;
zero.QuadPart = 0;
if (!SetFilePointerEx((HANDLE)f, zero, &new_offset, FILE_CURRENT)) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return (zip_int64_t)new_offset.QuadPart;
}
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 10000 + win32err;
}
}
static bool
_zip_stat_win32(zip_source_file_context_t *ctx, zip_source_file_stat_t *st, HANDLE h) {
FILETIME mtimeft;
time_t mtime;
LARGE_INTEGER size;
if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return false;
}
if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
return false;
}
st->exists = true;
st->mtime = mtime;
if (GetFileType(h) == FILE_TYPE_DISK) {
st->regular_file = 1;
if (!GetFileSizeEx(h, &size)) {
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
return false;
}
st->size = (zip_uint64_t)size.QuadPart;
}
/* TODO: fill in ctx->attributes */
return true;
}
bool
_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 false;
}
*t = temp;
return true;
}

View File

@ -0,0 +1,74 @@
#ifndef _HAD_ZIP_SOURCE_FILE_WIN32_H
#define _HAD_ZIP_SOURCE_FILE_WIN32_H
/*
zip_source_file_win32.h -- common header for Windows file implementation
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <aclapi.h>
#include "zipint.h"
#include "zip_source_file.h"
struct zip_win32_file_operations {
char *(*allocate_tempname)(const char *name, size_t extra_chars, size_t *lengthp);
HANDLE (__stdcall *create_file)(const void *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
BOOL (__stdcall *delete_file)(const void *name);
DWORD (__stdcall *get_file_attributes)(const void *name);
BOOL (__stdcall *get_file_attributes_ex)(const void *name, GET_FILEEX_INFO_LEVELS info_level, void *information);
void (*make_tempname)(char *buf, size_t len, const char *name, zip_uint32_t i);
BOOL (__stdcall *move_file)(const void *from, const void *to, DWORD flags);
BOOL (__stdcall *set_file_attributes)(const void *name, DWORD attributes);
char *(*string_duplicate)(const char *string);
};
typedef struct zip_win32_file_operations zip_win32_file_operations_t;
extern zip_source_file_operations_t _zip_source_file_win32_named_ops;
void _zip_win32_op_close(zip_source_file_context_t *ctx);
zip_int64_t _zip_win32_op_read(zip_source_file_context_t *ctx, void *buf, zip_uint64_t len);
bool _zip_win32_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, int whence);
zip_int64_t _zip_win32_op_tell(zip_source_file_context_t *ctx, void *f);
bool _zip_filetime_to_time_t(FILETIME ft, time_t *t);
int _zip_win32_error_to_errno(DWORD win32err);
#endif /* _HAD_ZIP_SOURCE_FILE_WIN32_H */

View File

@ -0,0 +1,268 @@
/*
zip_source_file_win32_named.c -- source for Windows file opened by name
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 "zip_source_file_win32.h"
static zip_int64_t _zip_win32_named_op_commit_write(zip_source_file_context_t *ctx);
static zip_int64_t _zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx);
static bool _zip_win32_named_op_open(zip_source_file_context_t *ctx);
static zip_int64_t _zip_win32_named_op_remove(zip_source_file_context_t *ctx);
static void _zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx);
static bool _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st);
static char *_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string);
static zip_int64_t _zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len);
static HANDLE win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes);
/* clang-format off */
zip_source_file_operations_t _zip_source_file_win32_named_ops = {
_zip_win32_op_close,
_zip_win32_named_op_commit_write,
_zip_win32_named_op_create_temp_output,
NULL,
_zip_win32_named_op_open,
_zip_win32_op_read,
_zip_win32_named_op_remove,
_zip_win32_named_op_rollback_write,
_zip_win32_op_seek,
_zip_win32_named_op_stat,
_zip_win32_named_op_string_duplicate,
_zip_win32_op_tell,
_zip_win32_named_op_write
};
/* clang-format on */
static zip_int64_t
_zip_win32_named_op_commit_write(zip_source_file_context_t *ctx) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
DWORD attributes;
if (!CloseHandle((HANDLE)ctx->fout)) {
zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
attributes = file_ops->get_file_attributes(ctx->tmpname);
if (attributes == INVALID_FILE_ATTRIBUTES) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
if (attributes & FILE_ATTRIBUTE_TEMPORARY) {
if (!file_ops->set_file_attributes(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY)) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
}
if (!file_ops->move_file(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING)) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return 0;
}
static zip_int64_t
_zip_win32_named_op_create_temp_output(zip_source_file_context_t *ctx) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
zip_uint32_t value, i;
HANDLE th = INVALID_HANDLE_VALUE;
void *temp = NULL;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_ATTRIBUTES psa = NULL;
SECURITY_ATTRIBUTES sa;
SECURITY_INFORMATION si;
DWORD success;
PACL dacl = NULL;
char *tempname = NULL;
size_t tempname_size = 0;
if ((HANDLE)ctx->f != INVALID_HANDLE_VALUE && GetFileType((HANDLE)ctx->f) == FILE_TYPE_DISK) {
si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
success = GetSecurityInfo((HANDLE)ctx->f, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
if (success == ERROR_SUCCESS) {
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = psd;
psa = &sa;
}
}
#ifndef MS_UWP
value = GetTickCount();
#else
value = (zip_uint32_t)(GetTickCount64() & 0xffffffff);
#endif
if ((tempname = file_ops->allocate_tempname(ctx->fname, 10, &tempname_size)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
file_ops->make_tempname(tempname, tempname_size, ctx->fname, value + i);
th = win32_named_open(ctx, tempname, true, psa);
if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
break;
}
if (th == INVALID_HANDLE_VALUE) {
free(tempname);
LocalFree(psd);
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
LocalFree(psd);
ctx->fout = th;
ctx->tmpname = tempname;
return 0;
}
static bool
_zip_win32_named_op_open(zip_source_file_context_t *ctx) {
HANDLE h = win32_named_open(ctx, ctx->fname, false, NULL);
if (h == INVALID_HANDLE_VALUE) {
return false;
}
ctx->f = h;
return true;
}
static zip_int64_t
_zip_win32_named_op_remove(zip_source_file_context_t *ctx) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
if (!file_ops->delete_file(ctx->fname)) {
zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
return 0;
}
static void
_zip_win32_named_op_rollback_write(zip_source_file_context_t *ctx) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
if (ctx->fout) {
CloseHandle((HANDLE)ctx->fout);
}
file_ops->delete_file(ctx->tmpname);
}
static bool
_zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
WIN32_FILE_ATTRIBUTE_DATA file_attributes;
if (!file_ops->get_file_attributes_ex(ctx->fname, GetFileExInfoStandard, &file_attributes)) {
DWORD error = GetLastError();
if (error == ERROR_FILE_NOT_FOUND) {
st->exists = false;
return true;
}
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(error));
return false;
}
st->exists = true;
st->regular_file = true; /* TODO: Is this always right? How to determine without a HANDLE? */
if (!_zip_filetime_to_time_t(file_attributes.ftLastWriteTime, &st->mtime)) {
zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
return false;
}
st->size = ((zip_uint64_t)file_attributes.nFileSizeHigh << 32) | file_attributes.nFileSizeLow;
/* TODO: fill in ctx->attributes */
return true;
}
static char *
_zip_win32_named_op_string_duplicate(zip_source_file_context_t *ctx, const char *string) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
return file_ops->string_duplicate(string);
}
static zip_int64_t
_zip_win32_named_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64_t len) {
DWORD ret;
if (!WriteFile((HANDLE)ctx->fout, 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;
}
static HANDLE
win32_named_open(zip_source_file_context_t *ctx, const char *name, bool temporary, PSECURITY_ATTRIBUTES security_attributes) {
zip_win32_file_operations_t *file_ops = (zip_win32_file_operations_t *)ctx->ops_userdata;
DWORD access = GENERIC_READ;
DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
DWORD creation_disposition = OPEN_EXISTING;
DWORD file_attributes = FILE_ATTRIBUTE_NORMAL;
HANDLE h;
if (temporary) {
access = GENERIC_READ | GENERIC_WRITE;
share_mode = FILE_SHARE_READ;
creation_disposition = CREATE_NEW;
file_attributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY;
}
h = file_ops->create_file(name, access, share_mode, security_attributes, creation_disposition, file_attributes, NULL);
if (h == INVALID_HANDLE_VALUE) {
zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
}
return h;
}

View File

@ -0,0 +1,117 @@
/*
zip_source_file_win32_utf16.c -- source for Windows file opened by UTF-16 name
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 "zip_source_file_win32.h"
#define RtlGenRandom SystemFunction036
BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length)
{
return RtlGenRandom (buffer, (ULONG) length);
}
static char *utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp);
static HANDLE __stdcall utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file);
static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
static char *utf16_strdup(const char *string);
zip_win32_file_operations_t ops_utf16 = {
utf16_allocate_tempname,
utf16_create_file,
DeleteFileW,
GetFileAttributesW,
GetFileAttributesExW,
utf16_make_tempname,
MoveFileExW,
SetFileAttributesW,
utf16_strdup
};
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_file_common_new((const char *)fname, NULL, start, length, NULL, &_zip_source_file_win32_named_ops, &ops_utf16, error);
}
static char *
utf16_allocate_tempname(const char *name, size_t extra_chars, size_t *lengthp) {
*lengthp = wcslen((const wchar_t *)name) + extra_chars;
return (char *)malloc(*lengthp * sizeof(wchar_t));
}
static HANDLE __stdcall
utf16_create_file(const char *name, DWORD access, DWORD share_mode, PSECURITY_ATTRIBUTES security_attributes, DWORD creation_disposition, DWORD file_attributes, HANDLE template_file) {
#ifdef MS_UWP
CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
extParams.dwFileAttributes = file_attributes;
extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extParams.dwSize = sizeof(extParams);
extParams.hTemplateFile = template_file;
extParams.lpSecurityAttributes = security_attributes;
return CreateFile2((const wchar_t *)name, access, share_mode, creation_disposition, &extParams);
#else
return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);
#endif
}
static void
utf16_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i) {
_snwprintf((wchar_t *)buf, len, L"%s.%08x", (const wchar_t *)name, i);
}
static char *
utf16_strdup(const char *string) {
return (char *)_wcsdup((const wchar_t *)string);
}

View File

@ -1,6 +1,6 @@
/*
zip_source_win32utf8.c -- create data source from Windows file (UTF-8)
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
zip_source_file_win32_ansi.c -- source for Windows file opened by UTF-8 name
Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -31,23 +31,14 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <stdlib.h>
#include "zipint.h"
#include "zipwin32.h"
#include "zip_source_file_win32.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;
if (za == NULL) {
return NULL;
}
return zip_source_file_create(fname, start, len, &za->error);
}
@ -59,24 +50,24 @@ zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length
zip_source_t *source;
if (fname == NULL || length < -1) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
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;
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;
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;
}

View File

@ -1,663 +0,0 @@
/*
zip_source_filep.c -- create data source from FILE *
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "zipint.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_CLONEFILE
#include <sys/attr.h>
#include <sys/clonefile.h>
#define CAN_CLONE
#endif
#ifdef HAVE_FICLONERANGE
#include <linux/fs.h>
#include <sys/ioctl.h>
#define CAN_CLONE
#endif
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_error_t stat_error; /* error returned for stat */
zip_uint64_t start; /* start offset of data to read */
zip_uint64_t end; /* end offset of data to read relative to start, 0 for up to EOF */
zip_uint64_t current; /* current offset relative to start (0 is beginning of part we read) */
/* 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);
#ifdef CAN_CLONE
static zip_int64_t create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset);
#endif
static FILE *_zip_fopen(const char *name, bool writeable);
static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error);
static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error);
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;
struct stat sb;
bool stat_valid;
if (file == NULL && fname == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if (len < 0) {
len = 0;
}
if (start > ZIP_INT64_MAX || start + (zip_uint64_t)len < start) {
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 = (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);
}
if (ctx->end > 0) {
ctx->st.size = ctx->end;
ctx->st.valid |= ZIP_STAT_SIZE;
}
zip_error_init(&ctx->stat_error);
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) {
stat_valid = stat(ctx->fname, &sb) >= 0;
if (!stat_valid) {
if (ctx->start == 0 && ctx->end == 0) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
}
else {
stat_valid = fstat(fileno(ctx->f), &sb) >= 0;
}
if (!stat_valid) {
zip_error_set(&ctx->stat_error, ZIP_ER_READ, errno);
}
else {
if ((ctx->st.valid & ZIP_STAT_MTIME) == 0) {
ctx->st.mtime = sb.st_mtime;
ctx->st.valid |= ZIP_STAT_MTIME;
}
if (S_ISREG(sb.st_mode)) {
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
if (ctx->start + ctx->end > (zip_uint64_t)sb.st_size) {
zip_error_set(error, ZIP_ER_INVAL, 0);
free(ctx->fname);
free(ctx);
return NULL;
}
if (ctx->end == 0) {
ctx->st.size = (zip_uint64_t)sb.st_size - ctx->start;
ctx->st.valid |= ZIP_STAT_SIZE;
if (ctx->fname && start == 0) {
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
}
}
}
}
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY);
#ifdef CAN_CLONE
if (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE)) {
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING);
}
#endif
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;
int mode;
FILE *tfp;
struct stat st;
if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
if (stat(ctx->fname, &st) == 0) {
mode = st.st_mode;
}
else {
mode = -1;
}
sprintf(temp, "%s.XXXXXX", ctx->fname);
if ((tfd = _zip_mkstempm(temp, mode)) == -1) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
free(temp);
return -1;
}
if ((tfp = fdopen(tfd, "r+b")) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
close(tfd);
(void)remove(temp);
free(temp);
return -1;
}
ctx->fout = tfp;
ctx->tmpname = temp;
return 0;
}
#ifdef CAN_CLONE
zip_int64_t static create_temp_output_cloning(struct read_file *ctx, zip_uint64_t offset) {
char *temp;
FILE *tfp;
if (offset > ZIP_OFF_MAX) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, E2BIG);
return -1;
}
if ((temp = (char *)malloc(strlen(ctx->fname) + 8)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
sprintf(temp, "%s.XXXXXX", ctx->fname);
#ifdef HAVE_CLONEFILE
#ifndef __clang_analyzer__
/* we can't use mkstemp, since clonefile insists on creating the file */
if (mktemp(temp) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
free(temp);
return -1;
}
#endif
if (clonefile(ctx->fname, temp, 0) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
free(temp);
return -1;
}
if ((tfp = _zip_fopen(temp, true)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
(void)remove(temp);
free(temp);
return -1;
}
#else
{
int fd;
struct file_clone_range range;
struct stat st;
if (fstat(fileno(ctx->f), &st) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
return -1;
}
if ((fd = mkstemp(temp)) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
free(temp);
return -1;
}
range.src_fd = fileno(ctx->f);
range.src_offset = 0;
range.src_length = ((offset + st.st_blksize - 1) / st.st_blksize) * st.st_blksize;
if (range.src_length > st.st_size) {
range.src_length = 0;
}
range.dest_offset = 0;
if (ioctl(fd, FICLONERANGE, &range) < 0) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
(void)close(fd);
(void)remove(temp);
free(temp);
return -1;
}
if ((tfp = fdopen(fd, "r+b")) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
(void)close(fd);
(void)remove(temp);
free(temp);
return -1;
}
}
#endif
if (ftruncate(fileno(tfp), (off_t)offset) < 0) {
(void)fclose(tfp);
(void)remove(temp);
free(temp);
return -1;
}
if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) {
(void)fclose(tfp);
(void)remove(temp);
free(temp);
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
}
ctx->fout = tfp;
ctx->tmpname = temp;
return 0;
}
#endif
static zip_int64_t
read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
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_ACCEPT_EMPTY:
return 0;
case ZIP_SOURCE_BEGIN_WRITE:
#ifdef _WIN32
return -1;
#else
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
return create_temp_output(ctx);
#endif
#ifdef CAN_CLONE
case ZIP_SOURCE_BEGIN_WRITE_CLONING:
if (ctx->fname == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
return -1;
}
return create_temp_output_cloning(ctx, len);
#endif
case ZIP_SOURCE_CLOSE:
if (ctx->fname) {
fclose(ctx->f);
ctx->f = NULL;
}
return 0;
case ZIP_SOURCE_COMMIT_WRITE: {
if (fclose(ctx->fout) < 0) {
ctx->fout = NULL;
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
}
ctx->fout = NULL;
if (rename(ctx->tmpname, ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_RENAME, errno);
return -1;
}
free(ctx->tmpname);
ctx->tmpname = 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 = _zip_fopen(ctx->fname, false)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_OPEN, errno);
return -1;
}
}
if (ctx->start > 0) {
if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
/* TODO: skip by reading */
return -1;
}
}
ctx->current = 0;
return 0;
case ZIP_SOURCE_READ:
if (ctx->end > 0) {
n = ctx->end - ctx->current;
if (n > len) {
n = len;
}
}
else {
n = len;
}
if (n > SIZE_MAX)
n = SIZE_MAX;
if ((i = fread(buf, 1, (size_t)n, ctx->f)) == 0) {
if (ferror(ctx->f)) {
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
return -1;
}
}
ctx->current += i;
return (zip_int64_t)i;
case ZIP_SOURCE_REMOVE:
if (remove(ctx->fname) < 0) {
zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
return -1;
}
return 0;
case ZIP_SOURCE_ROLLBACK_WRITE:
if (ctx->fout) {
fclose(ctx->fout);
ctx->fout = NULL;
}
(void)remove(ctx->tmpname);
free(ctx->tmpname);
ctx->tmpname = NULL;
return 0;
case ZIP_SOURCE_SEEK: {
zip_int64_t new_current;
int need_seek;
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
if (args == NULL)
return -1;
need_seek = 1;
switch (args->whence) {
case SEEK_SET:
new_current = args->offset;
break;
case SEEK_END:
if (ctx->end == 0) {
if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
return -1;
}
if ((new_current = ftello(ctx->f)) < 0) {
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
return -1;
}
new_current -= (zip_int64_t)ctx->start;
need_seek = 0;
}
else {
new_current = (zip_int64_t)ctx->end + args->offset;
}
break;
case SEEK_CUR:
new_current = (zip_int64_t)ctx->current + args->offset;
break;
default:
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
if (new_current < 0 || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end) || (zip_uint64_t)new_current + ctx->start < ctx->start) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
ctx->current = (zip_uint64_t)new_current;
if (need_seek) {
if (_zip_fseek_u(ctx->f, ctx->current + ctx->start, SEEK_SET, &ctx->error) < 0) {
return -1;
}
}
return 0;
}
case ZIP_SOURCE_SEEK_WRITE: {
zip_source_args_seek_t *args;
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 (zip_error_code_zip(&ctx->stat_error) != 0) {
zip_error_set(&ctx->error, zip_error_code_zip(&ctx->stat_error), zip_error_code_system(&ctx->stat_error));
return -1;
}
memcpy(data, &ctx->st, sizeof(ctx->st));
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;
}
/*
* fopen replacement that sets the close-on-exec flag
* some implementations support an fopen 'e' flag for that,
* but e.g. macOS doesn't.
*/
static FILE *
_zip_fopen(const char *name, bool writeable)
{
int fd;
int flags;
FILE *fp;
flags = O_CLOEXEC;
if (writeable) {
flags |= O_RDWR;
}
else {
flags |= O_RDONLY;
}
/* mode argument needed on Windows */
if ((fd = open(name, flags, 0666)) < 0) {
return NULL;
}
if ((fp = fdopen(fd, writeable ? "r+b" : "rb")) == NULL) {
return NULL;
}
return fp;
}

View File

@ -0,0 +1,104 @@
/*
zip_source_get_file_attributes.c -- get attributes for file from source
Copyright (C) 2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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_attributes_init(zip_file_attributes_t *attributes) {
attributes->valid = 0;
attributes->version = 1;
}
int
zip_source_get_file_attributes(zip_source_t *src, zip_file_attributes_t *attributes) {
if (src->source_closed) {
return -1;
}
if (attributes == NULL) {
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
return -1;
}
zip_file_attributes_init(attributes);
if (src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_FILE_ATTRIBUTES)) {
if (_zip_source_call(src, attributes, sizeof(*attributes), ZIP_SOURCE_GET_FILE_ATTRIBUTES) < 0) {
return -1;
}
}
if (ZIP_SOURCE_IS_LAYERED(src)) {
zip_file_attributes_t lower_attributes;
if (zip_source_get_file_attributes(src->src, &lower_attributes) < 0) {
_zip_error_set_from_source(&src->error, src->src);
return -1;
}
if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM) == 0) {
attributes->host_system = lower_attributes.host_system;
attributes->valid |= ZIP_FILE_ATTRIBUTES_HOST_SYSTEM;
}
if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_ASCII) && (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) == 0) {
attributes->ascii = lower_attributes.ascii;
attributes->valid |= ZIP_FILE_ATTRIBUTES_ASCII;
}
if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED)) {
if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
attributes->version_needed = ZIP_MAX(lower_attributes.version_needed, attributes->version_needed);
}
else {
attributes->version_needed = lower_attributes.version_needed;
attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
}
}
if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES) == 0) {
attributes->external_file_attributes = lower_attributes.external_file_attributes;
attributes->valid |= ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES;
}
if ((lower_attributes.valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS)) {
if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
attributes->general_purpose_bit_flags &= ~lower_attributes.general_purpose_bit_mask;
attributes->general_purpose_bit_flags |= lower_attributes.general_purpose_bit_flags & lower_attributes.general_purpose_bit_mask;
attributes->general_purpose_bit_mask |= lower_attributes.general_purpose_bit_mask;
}
else {
attributes->valid |= ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
attributes->general_purpose_bit_flags = lower_attributes.general_purpose_bit_flags;
attributes->general_purpose_bit_mask = lower_attributes.general_purpose_bit_mask;
}
}
}
return 0;
}

View File

@ -1,6 +1,6 @@
/*
zip_source_pkware.c -- Traditional PKWARE de/encryption routines
Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner
zip_source_pkware_decode.c -- Traditional PKWARE decryption routines
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -38,24 +38,20 @@
#include "zipint.h"
struct trad_pkware {
char *password;
zip_pkware_keys_t keys;
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 *);
static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);
static void trad_pkware_free(struct trad_pkware *);
zip_source_t *
zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
struct trad_pkware *ctx;
zip_source_t *s2;
@ -68,20 +64,12 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons
return NULL;
}
if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
if ((ctx = trad_pkware_new(password, &za->error)) == NULL) {
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);
trad_pkware_free(ctx);
return NULL;
}
@ -89,62 +77,52 @@ zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, cons
}
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];
zip_uint8_t header[ZIP_CRYPTO_PKWARE_HEADERLEN];
struct zip_stat st;
zip_int64_t n;
unsigned short dostime, dosdate;
bool ok;
if ((n = zip_source_read(src, header, HEADERLEN)) < 0) {
if ((n = zip_source_read(src, header, ZIP_CRYPTO_PKWARE_HEADERLEN)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
if (n != HEADERLEN) {
if (n != ZIP_CRYPTO_PKWARE_HEADERLEN) {
zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
return -1;
}
decrypt(ctx, header, header, HEADERLEN, 0);
_zip_pkware_decrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
if (zip_source_stat(src, &st) < 0) {
if (zip_source_stat(src, &st)) {
/* stat failed, skip password validation */
return 0;
}
_zip_u2d_time(st.mtime, &dostime, &dosdate);
/* password verification - two ways:
* mtime - InfoZIP way, to avoid computing complete CRC before encrypting data
* CRC - old PKWare way
*/
if (header[HEADERLEN - 1] != st.crc >> 24 && header[HEADERLEN - 1] != dostime >> 8) {
ok = false;
if (st.valid & ZIP_STAT_MTIME) {
unsigned short dostime, dosdate;
_zip_u2d_time(st.mtime, &dostime, &dosdate);
if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == dostime >> 8) {
ok = true;
}
}
if (st.valid & ZIP_STAT_CRC) {
if (header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] == st.crc >> 24) {
ok = true;
}
}
if (!ok && ((st.valid & (ZIP_STAT_MTIME | ZIP_STAT_CRC)) != 0)) {
zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
return -1;
}
@ -162,8 +140,11 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
switch (cmd) {
case ZIP_SOURCE_OPEN:
if (decrypt_header(src, ctx) < 0)
_zip_pkware_keys_reset(&ctx->keys);
_zip_pkware_decrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password));
if (decrypt_header(src, ctx) < 0) {
return -1;
}
return 0;
case ZIP_SOURCE_READ:
@ -172,7 +153,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
return -1;
}
decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
_zip_pkware_decrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n);
return n;
case ZIP_SOURCE_CLOSE:
@ -185,9 +166,9 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
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;
if (st->valid & ZIP_STAT_COMP_SIZE) {
st->comp_size -= ZIP_CRYPTO_PKWARE_HEADERLEN;
}
return 0;
}
@ -199,7 +180,7 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
return zip_error_to_data(&ctx->error, data, len);
case ZIP_SOURCE_FREE:
pkware_free(ctx);
trad_pkware_free(ctx);
return 0;
default:
@ -209,7 +190,33 @@ pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_so
}
static struct trad_pkware *
trad_pkware_new(const char *password, zip_error_t *error) {
struct trad_pkware *ctx;
if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if ((ctx->password = strdup(password)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
zip_error_init(&ctx->error);
return ctx;
}
static void
pkware_free(struct trad_pkware *ctx) {
trad_pkware_free(struct trad_pkware *ctx) {
if (ctx == NULL) {
return;
}
free(ctx->password);
free(ctx);
}

View File

@ -0,0 +1,249 @@
/*
zip_source_pkware_encode.c -- Traditional PKWARE encryption routines
Copyright (C) 2009-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 {
char *password;
zip_pkware_keys_t keys;
zip_buffer_t *buffer;
bool eof;
zip_error_t error;
};
static int encrypt_header(zip_source_t *, struct trad_pkware *);
static zip_int64_t pkware_encrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static void trad_pkware_free(struct trad_pkware *);
static struct trad_pkware *trad_pkware_new(const char *password, zip_error_t *error);
zip_source_t *
zip_source_pkware_encode(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 = trad_pkware_new(password, &za->error)) == NULL) {
return NULL;
}
if ((s2 = zip_source_layered(za, src, pkware_encrypt, ctx)) == NULL) {
trad_pkware_free(ctx);
return NULL;
}
return s2;
}
static int
encrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
struct zip_stat st;
unsigned short dostime, dosdate;
zip_uint8_t *header;
if (zip_source_stat(src, &st) != 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
_zip_u2d_time(st.mtime, &dostime, &dosdate);
if ((ctx->buffer = _zip_buffer_new(NULL, ZIP_CRYPTO_PKWARE_HEADERLEN)) == NULL) {
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
return -1;
}
header = _zip_buffer_data(ctx->buffer);
/* generate header from random bytes and mtime
see appnote.iz, XIII. Decryption, Step 2, last paragraph */
if (!zip_secure_random(header, ZIP_CRYPTO_PKWARE_HEADERLEN - 1)) {
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
_zip_buffer_free(ctx->buffer);
ctx->buffer = NULL;
return -1;
}
header[ZIP_CRYPTO_PKWARE_HEADERLEN - 1] = (zip_uint8_t)((dostime >> 8) & 0xff);
_zip_pkware_encrypt(&ctx->keys, header, header, ZIP_CRYPTO_PKWARE_HEADERLEN);
return 0;
}
static zip_int64_t
pkware_encrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t length, zip_source_cmd_t cmd) {
struct trad_pkware *ctx;
zip_int64_t n;
zip_uint64_t buffer_n;
ctx = (struct trad_pkware *)ud;
switch (cmd) {
case ZIP_SOURCE_OPEN:
ctx->eof = false;
/* initialize keys */
_zip_pkware_keys_reset(&ctx->keys);
_zip_pkware_encrypt(&ctx->keys, NULL, (const zip_uint8_t *)ctx->password, strlen(ctx->password));
if (encrypt_header(src, ctx) < 0) {
return -1;
}
return 0;
case ZIP_SOURCE_READ:
buffer_n = 0;
if (ctx->buffer) {
/* write header values to data */
buffer_n = _zip_buffer_read(ctx->buffer, data, length);
data = (zip_uint8_t *)data + buffer_n;
length -= buffer_n;
if (_zip_buffer_eof(ctx->buffer)) {
_zip_buffer_free(ctx->buffer);
ctx->buffer = NULL;
}
}
if (ctx->eof) {
return (zip_int64_t)buffer_n;
}
if ((n = zip_source_read(src, data, length)) < 0) {
_zip_error_set_from_source(&ctx->error, src);
return -1;
}
_zip_pkware_encrypt(&ctx->keys, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n);
if ((zip_uint64_t)n < length) {
ctx->eof = true;
}
return (zip_int64_t)buffer_n + n;
case ZIP_SOURCE_CLOSE:
_zip_buffer_free(ctx->buffer);
ctx->buffer = NULL;
return 0;
case ZIP_SOURCE_STAT: {
zip_stat_t *st;
st = (zip_stat_t *)data;
st->encryption_method = ZIP_EM_TRAD_PKWARE;
st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
if (st->valid & ZIP_STAT_COMP_SIZE) {
st->comp_size += ZIP_CRYPTO_PKWARE_HEADERLEN;
}
return 0;
}
case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;
if (length < sizeof(*attributes)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED;
attributes->version_needed = 20;
return 0;
}
case ZIP_SOURCE_SUPPORTS:
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);
case ZIP_SOURCE_ERROR:
return zip_error_to_data(&ctx->error, data, length);
case ZIP_SOURCE_FREE:
trad_pkware_free(ctx);
return 0;
default:
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
}
static struct trad_pkware *
trad_pkware_new(const char *password, zip_error_t *error) {
struct trad_pkware *ctx;
if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
if ((ctx->password = strdup(password)) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
free(ctx);
return NULL;
}
ctx->buffer = NULL;
zip_error_init(&ctx->error);
return ctx;
}
static void
trad_pkware_free(struct trad_pkware *ctx) {
if (ctx == NULL) {
return;
}
free(ctx->password);
_zip_buffer_free(ctx->buffer);
zip_error_fini(&ctx->error);
free(ctx);
}

View File

@ -1,135 +0,0 @@
/*
zip_source_win32a.c -- create data source from Windows file (ANSI)
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#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);
// clang-format off
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
};
// clang-format on
ZIP_EXTERN zip_source_t *
zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len) {
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) {
size_t 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) {
DWORD attributes = GetFileAttributesA(ctx->tmpname);
if (INVALID_FILE_ATTRIBUTES == attributes)
return -1;
if (FILE_ATTRIBUTE_TEMPORARY & attributes) {
if (!SetFileAttributesA(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY))
return -1;
}
if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
return -1;
return 0;
}
static int
_win32_remove_a(const void *fname) {
DeleteFileA((const char *)fname);
return 0;
}

View File

@ -1,602 +0,0 @@
/*
zip_source_win32file.c -- create data source from HANDLE (Win32)
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
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 <aclapi.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.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;
}
ctx->supports |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ACCEPT_EMPTY);
if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
free(ctx->fname);
free(ctx);
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_ACCEPT_EMPTY:
return 0;
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 + ctx->start;
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) {
win32err = GetLastError();
if (win32err == ERROR_FILE_NOT_FOUND || win32err == ERROR_PATH_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;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_ATTRIBUTES psa = NULL;
SECURITY_ATTRIBUTES sa;
SECURITY_INFORMATION si;
DWORD success;
PACL dacl = NULL;
/*
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;
success = GetSecurityInfo(ctx->h, SE_FILE_OBJECT, si, NULL, NULL, &dacl, NULL, &psd);
if (success == ERROR_SUCCESS) {
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = psd;
psa = &sa;
}
}
#ifndef MS_UWP
value = GetTickCount();
#else
value = (zip_uint32_t)GetTickCount64();
#endif
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);
LocalFree(psd);
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
return -1;
}
LocalFree(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;
}

View File

@ -1,159 +0,0 @@
/*
zip_source_win32w.c -- create data source from Windows file (UTF-16)
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#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);
// clang-format off
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
};
// clang-format on
ZIP_EXTERN zip_source_t *
zip_source_win32w(zip_t *za, const wchar_t *fname, zip_uint64_t start, zip_int64_t len) {
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) {
#ifdef MS_UWP
CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extParams.dwSize = sizeof(extParams);
extParams.hTemplateFile = NULL;
extParams.lpSecurityAttributes = NULL;
return CreateFile2(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &extParams);
#else
return CreateFileW(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
#endif
}
static HANDLE
_win32_create_temp_w(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa) {
size_t 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;
}
#ifdef MS_UWP
CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY;
extParams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
extParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extParams.dwSize = sizeof(extParams);
extParams.hTemplateFile = NULL;
extParams.lpSecurityAttributes = NULL;
return CreateFile2((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, CREATE_NEW, &extParams);
#else
return CreateFileW((const wchar_t *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
#endif
}
static int
_win32_rename_temp_w(_zip_source_win32_read_file_t *ctx) {
DWORD attributes = GetFileAttributesW(ctx->tmpname);
if (INVALID_FILE_ATTRIBUTES == attributes)
return -1;
if (FILE_ATTRIBUTE_TEMPORARY & attributes) {
if (!SetFileAttributesW(ctx->tmpname, attributes & ~FILE_ATTRIBUTE_TEMPORARY))
return -1;
}
if (!MoveFileExW(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
return -1;
return 0;
}
static int
_win32_remove_w(const void *fname) {
DeleteFileW((const wchar_t *)fname);
return 0;
}

View File

@ -48,7 +48,7 @@ struct window {
zip_uint64_t offset; /* offset in src for next read */
zip_stat_t stat;
zip_int8_t compression_flags;
zip_file_attributes_t attributes;
zip_error_t error;
zip_int64_t supports;
bool needs_seek;
@ -64,7 +64,7 @@ zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t
zip_source_t *
_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
struct window *ctx;
if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) {
@ -80,11 +80,16 @@ _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t lengt
ctx->start = start;
ctx->end = start + length;
zip_stat_init(&ctx->stat);
ctx->compression_flags = compression_flags;
if (attributes != NULL) {
memcpy(&ctx->attributes, attributes, sizeof(ctx->attributes));
}
else {
zip_file_attributes_init(&ctx->attributes);
}
ctx->source_archive = source_archive;
ctx->source_index = source_index;
zip_error_init(&ctx->error);
ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
if (st) {
@ -173,7 +178,7 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
return -1;
}
}
byte_array_fini(b);
}
@ -231,8 +236,14 @@ window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_sou
return 0;
}
case ZIP_SOURCE_GET_COMPRESSION_FLAGS:
return ctx->compression_flags;
case ZIP_SOURCE_GET_FILE_ATTRIBUTES:
if (len < sizeof(ctx->attributes)) {
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
return -1;
}
memcpy(data, &ctx->attributes, sizeof(ctx->attributes));
return sizeof(ctx->attributes);
case ZIP_SOURCE_SUPPORTS:
return ctx->supports;

View File

@ -33,7 +33,6 @@
#include <stdlib.h>
#include <string.h>
#include "zipint.h"

View File

@ -36,15 +36,19 @@
#include "zipint.h"
static void _zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de);
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_source_t *src, *s2;
struct zip_stat st;
zip_stat_t st;
zip_file_attributes_t attributes;
zip_dirent_t *de;
bool partial_data, needs_crc, needs_decrypt, needs_decompress;
if (za == NULL)
if (za == NULL) {
return NULL;
}
if (srcza == NULL || srcidx >= srcza->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
@ -61,8 +65,9 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
return NULL;
}
if (flags & ZIP_FL_ENCRYPTED)
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);
@ -95,8 +100,13 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
}
}
if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) {
return NULL;
}
_zip_file_attributes_from_dirent(&attributes, de);
if (st.comp_size == 0) {
return zip_source_buffer(za, NULL, 0, 0);
return zip_source_buffer_with_attributes(za, NULL, 0, 0, &attributes);
}
if (partial_data && !needs_decrypt && !needs_decompress) {
@ -108,17 +118,12 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
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, start, len, &st2, 0, srcza, srcidx, &za->error)) == NULL) {
if ((src = _zip_source_window_new(srcza->src, start, len, &st2, &attributes, srcza, srcidx, &za->error)) == NULL) {
return NULL;
}
}
else {
zip_dirent_t *de;
if ((de = _zip_get_dirent(srcza, srcidx, flags, &za->error)) == NULL) {
return NULL;
}
if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, (de->bitflags >> 1) & 3, srcza, srcidx, &za->error)) == NULL) {
if ((src = _zip_source_window_new(srcza->src, 0, st.comp_size, &st, &attributes, srcza, srcidx, &za->error)) == NULL) {
return NULL;
}
}
@ -173,3 +178,14 @@ _zip_source_zip_new(zip_t *za, zip_t *srcza, zip_uint64_t srcidx, zip_flags_t fl
return src;
}
static void
_zip_file_attributes_from_dirent(zip_file_attributes_t *attributes, zip_dirent_t *de) {
zip_file_attributes_init(attributes);
attributes->valid = ZIP_FILE_ATTRIBUTES_ASCII | ZIP_FILE_ATTRIBUTES_HOST_SYSTEM | ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
attributes->ascii = de->int_attrib & 1;
attributes->host_system = de->version_madeby >> 8;
attributes->external_file_attributes = de->ext_attrib;
attributes->general_purpose_bit_flags = de->bitflags;
attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
}

View File

@ -34,10 +34,10 @@
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "zipint.h"
zip_uint32_t
_zip_string_crc32(const zip_string_t *s) {
zip_uint32_t crc;
@ -145,7 +145,7 @@ _zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags,
return NULL;
}
if ((s->raw = (zip_uint8_t *)malloc((size_t)(length + 1))) == NULL) {
if ((s->raw = (zip_uint8_t *)malloc((size_t)length + 1)) == NULL) {
free(s);
return NULL;
}

View File

@ -32,8 +32,6 @@
*/
#include <stdlib.h>
#include "zipint.h"

View File

@ -34,10 +34,7 @@
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "compat.h"
#ifdef ZIP_ALLOCATE_BUFFER
@ -69,6 +66,9 @@
#define BUFSIZE 8192
#define EFZIP64SIZE 28
#define EF_WINZIP_AES_SIZE 7
#define MAX_DATA_DESCRIPTOR_LENGTH 24
#define ZIP_CRYPTO_PKWARE_HEADERLEN 12
#define ZIP_CM_REPLACED_DEFAULT (-2)
#define ZIP_CM_WINZIP_AES 99 /* Winzip AES encrypted */
@ -95,6 +95,7 @@
/* 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_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK 0x0836
#define ZIP_MAX(a, b) ((a) > (b) ? (a) : (b))
#define ZIP_MIN(a, b) ((a) < (b) ? (a) : (b))
@ -111,14 +112,14 @@ typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *,
zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t method, int operation);
// clang-format off
/* clang-format off */
enum zip_compression_status {
ZIP_COMPRESSION_OK,
ZIP_COMPRESSION_END,
ZIP_COMPRESSION_ERROR,
ZIP_COMPRESSION_NEED_DATA
};
// clang-format on
/* clang-format on */
typedef enum zip_compression_status zip_compression_status_t;
struct zip_compression_algorithm {
@ -128,7 +129,9 @@ struct zip_compression_algorithm {
void (*deallocate)(void *ctx);
/* get compression specific general purpose bitflags */
int (*compression_flags)(void *ctx);
zip_uint16_t (*general_purpose_bit_flags)(void *ctx);
/* minimum version needed when using this algorithm */
zip_uint8_t version_needed;
/* start processing */
bool (*start)(void *ctx);
@ -154,8 +157,6 @@ extern zip_compression_algorithm_t zip_algorithm_xz_compress;
extern zip_compression_algorithm_t zip_algorithm_xz_decompress;
bool zip_compression_method_supported(zip_int32_t method, bool compress);
/* 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 *);
@ -170,13 +171,14 @@ zip_source_t *zip_source_crc(zip_t *, zip_source_t *, int);
zip_source_t *zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t cm);
zip_source_t *zip_source_layered(zip_t *, zip_source_t *, zip_source_layered_callback, void *);
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 *);
zip_source_t *zip_source_pkware_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_source_t *zip_source_pkware_encode(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);
zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes);
/* error source for layered sources */
@ -381,13 +383,13 @@ struct zip_string {
for those, use malloc()/free() */
#ifdef ZIP_ALLOCATE_BUFFER
#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf
#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL)
#define byte_array_fini(buf) (free(buf))
#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t *buf
#define byte_array_init(buf, size) (((buf) = (zip_uint8_t *)malloc(size)) != NULL)
#define byte_array_fini(buf) (free(buf))
#else
#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size]
#define byte_array_init(buf, size) (1)
#define byte_array_fini(buf) ((void)0)
#define DEFINE_BYTE_ARRAY(buf, size) zip_uint8_t buf[size]
#define byte_array_init(buf, size) (1)
#define byte_array_fini(buf) ((void)0)
#endif
@ -414,6 +416,11 @@ typedef struct zip_filelist zip_filelist_t;
struct _zip_winzip_aes;
typedef struct _zip_winzip_aes zip_winzip_aes_t;
struct _zip_pkware_keys {
zip_uint32_t key[3];
};
typedef struct _zip_pkware_keys zip_pkware_keys_t;
extern const char *const _zip_err_str[];
extern const int _zip_nerr_str;
extern const int _zip_err_type[];
@ -466,7 +473,6 @@ 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 *);
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error);
zip_cdir_t *_zip_cdir_new(zip_uint64_t, zip_error_t *);
@ -474,6 +480,7 @@ zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint6
time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
void _zip_deregister_source(zip_t *za, zip_source_t *src);
void _zip_dirent_apply_attributes(zip_dirent_t *, zip_file_attributes_t *, bool, zip_uint32_t);
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *);
void _zip_dirent_free(zip_dirent_t *);
void _zip_dirent_finalize(zip_dirent_t *);
@ -512,8 +519,6 @@ int _zip_file_fillbuf(void *, size_t, zip_file_t *);
zip_uint64_t _zip_file_get_end(const zip_t *za, zip_uint64_t index, zip_error_t *error);
zip_uint64_t _zip_file_get_offset(const zip_t *, zip_uint64_t, zip_error_t *);
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);
@ -545,7 +550,7 @@ int _zip_read(zip_source_t *src, zip_uint8_t *data, zip_uint64_t length, zip_err
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);
zip_string_t *_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t length, 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);
@ -554,12 +559,11 @@ bool zip_source_accept_empty(zip_source_t *src);
zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command);
bool _zip_source_eof(zip_source_t *);
zip_source_t *_zip_source_file_or_p(const char *, FILE *, zip_uint64_t, zip_int64_t, const zip_stat_t *, zip_error_t *error);
zip_int8_t zip_source_get_compression_flags(zip_source_t *);
bool _zip_source_had_error(zip_source_t *);
void _zip_source_invalidate(zip_source_t *src);
zip_source_t *_zip_source_new(zip_error_t *error);
int _zip_source_set_source_archive(zip_source_t *, zip_t *);
zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error);
zip_source_t *_zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_file_attributes_t *attributes, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error);
zip_source_t *_zip_source_zip_new(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_uint64_t, const char *);
int _zip_stat_merge(zip_stat_t *dst, const zip_stat_t *src, zip_error_t *error);
@ -576,6 +580,12 @@ bool _zip_winzip_aes_finish(zip_winzip_aes_t *ctx, zip_uint8_t *hmac);
void _zip_winzip_aes_free(zip_winzip_aes_t *ctx);
zip_winzip_aes_t *_zip_winzip_aes_new(const zip_uint8_t *password, zip_uint64_t password_length, const zip_uint8_t *salt, zip_uint16_t key_size, zip_uint8_t *password_verify, zip_error_t *error);
void _zip_pkware_encrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len);
void _zip_pkware_decrypt(zip_pkware_keys_t *keys, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len);
zip_pkware_keys_t *_zip_pkware_keys_new(zip_error_t *error);
void _zip_pkware_keys_free(zip_pkware_keys_t *keys);
void _zip_pkware_keys_reset(zip_pkware_keys_t *keys);
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);

View File

@ -1,85 +0,0 @@
#ifndef _HAD_ZIPWIN32_H
#define _HAD_ZIPWIN32_H
/*
zipwin32.h -- internal declarations for Windows.
Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* 0x0501 => Windows XP; needs to be at least this value because of GetFileSizeEx */
#if !defined(MS_UWP) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
/* 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 */