mirror of
https://github.com/vlang/v.git
synced 2025-09-08 23:07:19 -04:00
thirdparty: update zip
to commit 6f2116d from https://github.com/kuba--/zip/ (#21121)
This commit is contained in:
parent
9c9608b4e6
commit
4aba08dfe1
38
thirdparty/zip/miniz.h
vendored
38
thirdparty/zip/miniz.h
vendored
@ -4968,20 +4968,36 @@ static FILE *mz_fopen(const char *pFilename, const char *pMode) {
|
||||
WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
|
||||
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
|
||||
FILE *pFile = NULL;
|
||||
#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
|
||||
pFile = _wfopen(wFilename, wMode);
|
||||
#else
|
||||
errno_t err = _wfopen_s(&pFile, wFilename, wMode);
|
||||
#endif
|
||||
free(wFilename);
|
||||
free(wMode);
|
||||
#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
|
||||
return pFile;
|
||||
#else
|
||||
return err ? NULL : pFile;
|
||||
#endif
|
||||
}
|
||||
|
||||
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||
WCHAR *wPath = mz_utf8z_to_widechar(pPath);
|
||||
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
|
||||
FILE *pFile = NULL;
|
||||
#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
|
||||
pFile = _wfreopen(wPath, wMode, pStream);
|
||||
#else
|
||||
errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
|
||||
#endif
|
||||
free(wPath);
|
||||
free(wMode);
|
||||
#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
|
||||
return pFile;
|
||||
#else
|
||||
return err ? NULL : pFile;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mz_stat64(const char *path, struct __stat64 *buffer) {
|
||||
@ -4999,15 +5015,12 @@ static int mz_mkdir(const char *pDirname) {
|
||||
}
|
||||
|
||||
#ifndef MINIZ_NO_TIME
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
|
||||
#include <utime.h>
|
||||
#include <utime.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define MZ_FOPEN mz_fopen
|
||||
#define MZ_FCLOSE fclose
|
||||
#define MZ_FREAD fread
|
||||
@ -5022,11 +5035,13 @@ static int mz_mkdir(const char *pDirname) {
|
||||
#define MZ_MKDIR(d) mz_mkdir(d)
|
||||
|
||||
#elif defined(__MINGW32__) || defined(__WATCOMC__)
|
||||
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <sys/utime.h>
|
||||
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
|
||||
#include <utime.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MZ_FOPEN(f, m) fopen(f, m)
|
||||
#define MZ_FCLOSE fclose
|
||||
#define MZ_FREAD fread
|
||||
@ -5041,15 +5056,12 @@ static int mz_mkdir(const char *pDirname) {
|
||||
#define MZ_MKDIR(d) _mkdir(d)
|
||||
|
||||
#elif defined(__TINYC__)
|
||||
|
||||
#ifndef MINIZ_NO_TIME
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
|
||||
#include <utime.h>
|
||||
#include <utime.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#define MZ_FOPEN(f, m) fopen(f, m)
|
||||
#define MZ_FCLOSE fclose
|
||||
|
345
thirdparty/zip/zip.c
vendored
345
thirdparty/zip/zip.c
vendored
@ -18,7 +18,6 @@
|
||||
/* Win32, DOS, MSVC, MSVS */
|
||||
#include <direct.h>
|
||||
|
||||
#define STRCLONE(STR) ((STR) ? _strdup(STR) : NULL)
|
||||
#define HAS_DEVICE(P) \
|
||||
((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \
|
||||
(P)[1] == ':')
|
||||
@ -27,7 +26,6 @@
|
||||
#else
|
||||
|
||||
#include <unistd.h> // needed for symlink()
|
||||
#define STRCLONE(STR) ((STR) ? strdup(STR) : NULL)
|
||||
|
||||
#endif
|
||||
|
||||
@ -87,7 +85,7 @@ struct zip_entry_t {
|
||||
mz_uint64 uncomp_size;
|
||||
mz_uint64 comp_size;
|
||||
mz_uint32 uncomp_crc32;
|
||||
mz_uint64 offset;
|
||||
mz_uint64 dir_offset;
|
||||
mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
|
||||
mz_uint64 header_offset;
|
||||
mz_uint16 method;
|
||||
@ -215,6 +213,22 @@ static int zip_mkpath(char *path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *zip_strclone(const char *str, size_t n) {
|
||||
char c;
|
||||
size_t i;
|
||||
char *rpl = (char *)calloc((1 + n), sizeof(char));
|
||||
char *begin = rpl;
|
||||
if (!rpl) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; (i < n) && (c = *str++); ++i) {
|
||||
*rpl++ = c;
|
||||
}
|
||||
|
||||
return begin;
|
||||
}
|
||||
|
||||
static char *zip_strrpl(const char *str, size_t n, char oldchar, char newchar) {
|
||||
char c;
|
||||
size_t i;
|
||||
@ -234,57 +248,53 @@ static char *zip_strrpl(const char *str, size_t n, char oldchar, char newchar) {
|
||||
return begin;
|
||||
}
|
||||
|
||||
static inline int zip_strchr_match(const char *const str, size_t len, char c) {
|
||||
size_t i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (str[i] != c) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *zip_name_normalize(char *name, char *const nname, size_t len) {
|
||||
size_t offn = 0;
|
||||
size_t offnn = 0, ncpy = 0;
|
||||
size_t offn = 0, ncpy = 0;
|
||||
char c;
|
||||
|
||||
if (name == NULL || nname == NULL || len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
// skip trailing '/'
|
||||
while (ISSLASH(*name))
|
||||
while (ISSLASH(*name)) {
|
||||
name++;
|
||||
}
|
||||
|
||||
for (; offn < len; offn++) {
|
||||
if (ISSLASH(name[offn])) {
|
||||
if (ncpy > 0 && strcmp(&nname[offnn], ".\0") &&
|
||||
strcmp(&nname[offnn], "..\0")) {
|
||||
offnn += ncpy;
|
||||
nname[offnn++] = name[offn]; // append '/'
|
||||
while ((c = *name++)) {
|
||||
if (ISSLASH(c)) {
|
||||
if (ncpy > 0 && !zip_strchr_match(&nname[offn], ncpy, '.')) {
|
||||
offn += ncpy;
|
||||
nname[offn++] = c; // append '/'
|
||||
}
|
||||
ncpy = 0;
|
||||
} else {
|
||||
nname[offnn + ncpy] = name[offn];
|
||||
ncpy++;
|
||||
nname[offn + ncpy] = c;
|
||||
if (c) {
|
||||
ncpy++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at the end, extra check what we've already copied
|
||||
if (ncpy == 0 || !strcmp(&nname[offnn], ".\0") ||
|
||||
!strcmp(&nname[offnn], "..\0")) {
|
||||
nname[offnn] = 0;
|
||||
if (!zip_strchr_match(&nname[offn], ncpy, '.')) {
|
||||
nname[offn + ncpy] = '\0';
|
||||
} else {
|
||||
nname[offn] = '\0';
|
||||
}
|
||||
|
||||
return nname;
|
||||
}
|
||||
|
||||
static mz_bool zip_name_match(const char *name1, const char *name2) {
|
||||
char *nname2 = NULL;
|
||||
|
||||
#ifdef ZIP_RAW_ENTRYNAME
|
||||
nname2 = STRCLONE(name2);
|
||||
#else
|
||||
nname2 = zip_strrpl(name2, strlen(name2), '\\', '/');
|
||||
#endif
|
||||
|
||||
if (!nname2) {
|
||||
return MZ_FALSE;
|
||||
}
|
||||
|
||||
mz_bool res = (strcmp(name1, nname2) == 0) ? MZ_TRUE : MZ_FALSE;
|
||||
CLEANUP(nname2);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int zip_archive_truncate(mz_zip_archive *pzip) {
|
||||
mz_zip_internal_state *pState = pzip->m_pState;
|
||||
mz_uint64 file_size = pzip->m_archive_size;
|
||||
@ -325,7 +335,7 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir,
|
||||
#if defined(_MSC_VER)
|
||||
strcpy_s(path, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE, dir);
|
||||
#else
|
||||
strcpy(path, dir);
|
||||
strncpy(path, dir, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE);
|
||||
#endif
|
||||
|
||||
if (!ISSLASH(path[dirlen - 1])) {
|
||||
@ -454,7 +464,7 @@ static ssize_t zip_entry_mark(struct zip_t *zip,
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < len; ++j) {
|
||||
if (zip_name_match(zip->entry.name, entries[j])) {
|
||||
if (strcmp(zip->entry.name, entries[j]) == 0) {
|
||||
name_matches = MZ_TRUE;
|
||||
break;
|
||||
}
|
||||
@ -654,6 +664,35 @@ static ssize_t zip_entry_setbyindex(struct zip_t *zip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t zip_mem_move(void *pBuf, size_t bufSize, const mz_uint64 to,
|
||||
const mz_uint64 from, const size_t length) {
|
||||
uint8_t *dst = NULL, *src = NULL, *end = NULL;
|
||||
|
||||
if (!pBuf) {
|
||||
return ZIP_EINVIDX;
|
||||
}
|
||||
|
||||
end = (uint8_t *)pBuf + bufSize;
|
||||
|
||||
if (to > bufSize) {
|
||||
return ZIP_EINVIDX;
|
||||
}
|
||||
|
||||
if (from > bufSize) {
|
||||
return ZIP_EINVIDX;
|
||||
}
|
||||
|
||||
dst = (uint8_t *)pBuf + to;
|
||||
src = (uint8_t *)pBuf + from;
|
||||
|
||||
if (((dst + length) > end) || ((src + length) > end)) {
|
||||
return ZIP_EINVIDX;
|
||||
}
|
||||
|
||||
memmove(dst, src, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static ssize_t zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to,
|
||||
const mz_uint64 from, const size_t length,
|
||||
mz_uint8 *move_buf, const size_t capacity_size) {
|
||||
@ -675,10 +714,12 @@ static ssize_t zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to,
|
||||
return (ssize_t)length;
|
||||
}
|
||||
|
||||
static ssize_t zip_files_move(MZ_FILE *m_pFile, mz_uint64 writen_num,
|
||||
static ssize_t zip_files_move(struct zip_t *zip, mz_uint64 writen_num,
|
||||
mz_uint64 read_num, size_t length) {
|
||||
ssize_t n = 0;
|
||||
const size_t page_size = 1 << 12; // 4K
|
||||
mz_zip_internal_state *pState = zip->archive.m_pState;
|
||||
|
||||
mz_uint8 *move_buf = (mz_uint8 *)calloc(1, page_size);
|
||||
if (!move_buf) {
|
||||
return ZIP_EOOMEM;
|
||||
@ -688,8 +729,17 @@ static ssize_t zip_files_move(MZ_FILE *m_pFile, mz_uint64 writen_num,
|
||||
ssize_t move_count = 0;
|
||||
while ((mz_int64)length > 0) {
|
||||
move_count = (length >= page_size) ? page_size : length;
|
||||
n = zip_file_move(m_pFile, writen_num, read_num, move_count, move_buf,
|
||||
page_size);
|
||||
|
||||
if (pState->m_pFile) {
|
||||
n = zip_file_move(pState->m_pFile, writen_num, read_num, move_count,
|
||||
move_buf, page_size);
|
||||
} else if (pState->m_pMem) {
|
||||
n = zip_mem_move(pState->m_pMem, pState->m_mem_size, writen_num, read_num,
|
||||
move_count);
|
||||
} else {
|
||||
return ZIP_ENOFILE;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
moved_length = n;
|
||||
goto cleanup;
|
||||
@ -831,9 +881,11 @@ static ssize_t zip_entries_delete_mark(struct zip_t *zip,
|
||||
mz_zip_internal_state *pState = zip->archive.m_pState;
|
||||
zip->archive.m_zip_mode = MZ_ZIP_MODE_WRITING;
|
||||
|
||||
if ((!pState->m_pFile) || MZ_FSEEK64(pState->m_pFile, 0, SEEK_SET)) {
|
||||
CLEANUP(deleted_entry_flag_array);
|
||||
return ZIP_ENOENT;
|
||||
if (pState->m_pFile) {
|
||||
if (MZ_FSEEK64(pState->m_pFile, 0, SEEK_SET)) {
|
||||
CLEANUP(deleted_entry_flag_array);
|
||||
return ZIP_ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
while (i < entry_num) {
|
||||
@ -866,7 +918,7 @@ static ssize_t zip_entries_delete_mark(struct zip_t *zip,
|
||||
i++;
|
||||
}
|
||||
|
||||
n = zip_files_move(pState->m_pFile, writen_num, read_num, move_length);
|
||||
n = zip_files_move(zip, writen_num, read_num, move_length);
|
||||
if (n != (ssize_t)move_length) {
|
||||
CLEANUP(deleted_entry_flag_array);
|
||||
return n;
|
||||
@ -917,6 +969,7 @@ struct zip_t *zip_openwitherror(const char *zipname, int level, char mode,
|
||||
}
|
||||
|
||||
zip->level = (mz_uint)level;
|
||||
zip->entry.index = -1;
|
||||
switch (mode) {
|
||||
case 'w':
|
||||
// Create a new archive.
|
||||
@ -1029,33 +1082,18 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
return ZIP_EINVENTNAME;
|
||||
}
|
||||
|
||||
/*
|
||||
.ZIP File Format Specification Version: 6.3.3
|
||||
|
||||
4.4.17.1 The name of the file, with optional relative path.
|
||||
The path stored MUST not contain a drive or
|
||||
device letter, or a leading slash. All slashes
|
||||
MUST be forward slashes '/' as opposed to
|
||||
backwards slashes '\' for compatibility with Amiga
|
||||
and UNIX file systems etc. If input came from standard
|
||||
input, there is no file name field.
|
||||
*/
|
||||
if (zip->entry.name) {
|
||||
CLEANUP(zip->entry.name);
|
||||
}
|
||||
#ifdef ZIP_RAW_ENTRYNAME
|
||||
zip->entry.name = STRCLONE(entryname);
|
||||
#else
|
||||
zip->entry.name = zip_strrpl(entryname, entrylen, '\\', '/');
|
||||
#endif
|
||||
|
||||
if (!zip->entry.name) {
|
||||
// Cannot parse zip entry name
|
||||
return ZIP_EINVENTNAME;
|
||||
}
|
||||
|
||||
pzip = &(zip->archive);
|
||||
if (pzip->m_zip_mode == MZ_ZIP_MODE_READING) {
|
||||
zip->entry.name = zip_strclone(entryname, entrylen);
|
||||
if (!zip->entry.name) {
|
||||
// Cannot parse zip entry name
|
||||
return ZIP_EINVENTNAME;
|
||||
}
|
||||
|
||||
zip->entry.index = (ssize_t)mz_zip_reader_locate_file(
|
||||
pzip, zip->entry.name, NULL,
|
||||
case_sensitive ? MZ_ZIP_FLAG_CASE_SENSITIVE : 0);
|
||||
@ -1072,7 +1110,7 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
zip->entry.comp_size = stats.m_comp_size;
|
||||
zip->entry.uncomp_size = stats.m_uncomp_size;
|
||||
zip->entry.uncomp_crc32 = stats.m_crc32;
|
||||
zip->entry.offset = stats.m_central_dir_ofs;
|
||||
zip->entry.dir_offset = stats.m_central_dir_ofs;
|
||||
zip->entry.header_offset = stats.m_local_header_ofs;
|
||||
zip->entry.method = stats.m_method;
|
||||
zip->entry.external_attr = stats.m_external_attr;
|
||||
@ -1083,13 +1121,30 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
.ZIP File Format Specification Version: 6.3.3
|
||||
|
||||
4.4.17.1 The name of the file, with optional relative path.
|
||||
The path stored MUST not contain a drive or
|
||||
device letter, or a leading slash. All slashes
|
||||
MUST be forward slashes '/' as opposed to
|
||||
backwards slashes '\' for compatibility with Amiga
|
||||
and UNIX file systems etc. If input came from standard
|
||||
input, there is no file name field.
|
||||
*/
|
||||
zip->entry.name = zip_strrpl(entryname, entrylen, '\\', '/');
|
||||
if (!zip->entry.name) {
|
||||
// Cannot parse zip entry name
|
||||
return ZIP_EINVENTNAME;
|
||||
}
|
||||
|
||||
level = zip->level & 0xF;
|
||||
|
||||
zip->entry.index = (ssize_t)zip->archive.m_total_files;
|
||||
zip->entry.comp_size = 0;
|
||||
zip->entry.uncomp_size = 0;
|
||||
zip->entry.uncomp_crc32 = MZ_CRC32_INIT;
|
||||
zip->entry.offset = zip->archive.m_archive_size;
|
||||
zip->entry.dir_offset = zip->archive.m_archive_size;
|
||||
zip->entry.header_offset = zip->archive.m_archive_size;
|
||||
memset(zip->entry.header, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE * sizeof(mz_uint8));
|
||||
zip->entry.method = level ? MZ_DEFLATED : 0;
|
||||
@ -1116,7 +1171,7 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_write_zeros(pzip, zip->entry.offset,
|
||||
if (!mz_zip_writer_write_zeros(pzip, zip->entry.dir_offset,
|
||||
num_alignment_padding_bytes)) {
|
||||
// Cannot memset zip entry header
|
||||
err = ZIP_EMEMSET;
|
||||
@ -1146,7 +1201,8 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zip->entry.header_offset = zip->entry.offset + num_alignment_padding_bytes;
|
||||
zip->entry.header_offset =
|
||||
zip->entry.dir_offset + num_alignment_padding_bytes;
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.header_offset,
|
||||
zip->entry.header,
|
||||
@ -1160,28 +1216,29 @@ static int _zip_entry_open(struct zip_t *zip, const char *entryname,
|
||||
MZ_ASSERT(
|
||||
(zip->entry.header_offset & (pzip->m_file_offset_alignment - 1)) == 0);
|
||||
}
|
||||
zip->entry.offset += num_alignment_padding_bytes + sizeof(zip->entry.header);
|
||||
zip->entry.dir_offset +=
|
||||
num_alignment_padding_bytes + sizeof(zip->entry.header);
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, zip->entry.name,
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.dir_offset, zip->entry.name,
|
||||
entrylen) != entrylen) {
|
||||
// Cannot write data to zip entry
|
||||
err = ZIP_EWRTENT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zip->entry.offset += entrylen;
|
||||
zip->entry.dir_offset += entrylen;
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, extra_data,
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.dir_offset, extra_data,
|
||||
extra_size) != extra_size) {
|
||||
// Cannot write ZIP64 data to zip entry
|
||||
err = ZIP_EWRTENT;
|
||||
goto cleanup;
|
||||
}
|
||||
zip->entry.offset += extra_size;
|
||||
zip->entry.dir_offset += extra_size;
|
||||
|
||||
if (level) {
|
||||
zip->entry.state.m_pZip = pzip;
|
||||
zip->entry.state.m_cur_archive_file_ofs = zip->entry.offset;
|
||||
zip->entry.state.m_cur_archive_file_ofs = zip->entry.dir_offset;
|
||||
zip->entry.state.m_comp_size = 0;
|
||||
|
||||
if (tdefl_init(&(zip->entry.comp), mz_zip_writer_add_put_buf_callback,
|
||||
@ -1244,26 +1301,11 @@ int zip_entry_openbyindex(struct zip_t *zip, size_t index) {
|
||||
namelen = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
|
||||
pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
|
||||
|
||||
/*
|
||||
.ZIP File Format Specification Version: 6.3.3
|
||||
|
||||
4.4.17.1 The name of the file, with optional relative path.
|
||||
The path stored MUST not contain a drive or
|
||||
device letter, or a leading slash. All slashes
|
||||
MUST be forward slashes '/' as opposed to
|
||||
backwards slashes '\' for compatibility with Amiga
|
||||
and UNIX file systems etc. If input came from standard
|
||||
input, there is no file name field.
|
||||
*/
|
||||
if (zip->entry.name) {
|
||||
CLEANUP(zip->entry.name);
|
||||
}
|
||||
#ifdef ZIP_RAW_ENTRYNAME
|
||||
zip->entry.name = STRCLONE(pFilename);
|
||||
#else
|
||||
zip->entry.name = zip_strrpl(pFilename, namelen, '\\', '/');
|
||||
#endif
|
||||
|
||||
zip->entry.name = zip_strclone(pFilename, namelen);
|
||||
if (!zip->entry.name) {
|
||||
// local entry name is NULL
|
||||
return ZIP_EINVENTNAME;
|
||||
@ -1277,7 +1319,7 @@ int zip_entry_openbyindex(struct zip_t *zip, size_t index) {
|
||||
zip->entry.comp_size = stats.m_comp_size;
|
||||
zip->entry.uncomp_size = stats.m_uncomp_size;
|
||||
zip->entry.uncomp_crc32 = stats.m_crc32;
|
||||
zip->entry.offset = stats.m_central_dir_ofs;
|
||||
zip->entry.dir_offset = stats.m_central_dir_ofs;
|
||||
zip->entry.header_offset = stats.m_local_header_ofs;
|
||||
zip->entry.method = stats.m_method;
|
||||
zip->entry.external_attr = stats.m_external_attr;
|
||||
@ -1321,7 +1363,7 @@ int zip_entry_close(struct zip_t *zip) {
|
||||
goto cleanup;
|
||||
}
|
||||
zip->entry.comp_size = zip->entry.state.m_comp_size;
|
||||
zip->entry.offset = zip->entry.state.m_cur_archive_file_ofs;
|
||||
zip->entry.dir_offset = zip->entry.state.m_cur_archive_file_ofs;
|
||||
zip->entry.method = MZ_DEFLATED;
|
||||
}
|
||||
|
||||
@ -1335,13 +1377,14 @@ int zip_entry_close(struct zip_t *zip) {
|
||||
MZ_WRITE_LE64(local_dir_footer + 8, zip->entry.comp_size);
|
||||
MZ_WRITE_LE64(local_dir_footer + 16, zip->entry.uncomp_size);
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, local_dir_footer,
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.dir_offset,
|
||||
local_dir_footer,
|
||||
local_dir_footer_size) != local_dir_footer_size) {
|
||||
// Cannot write zip entry header
|
||||
err = ZIP_EWRTHDR;
|
||||
goto cleanup;
|
||||
}
|
||||
zip->entry.offset += local_dir_footer_size;
|
||||
zip->entry.dir_offset += local_dir_footer_size;
|
||||
|
||||
pExtra_data = extra_data;
|
||||
extra_size = mz_zip_writer_create_zip64_extra_data(
|
||||
@ -1352,7 +1395,7 @@ int zip_entry_close(struct zip_t *zip) {
|
||||
(zip->entry.header_offset >= MZ_UINT32_MAX) ? &zip->entry.header_offset
|
||||
: NULL);
|
||||
|
||||
if ((entrylen) && (zip->entry.name[entrylen - 1] == '/') &&
|
||||
if ((entrylen) && ISSLASH(zip->entry.name[entrylen - 1]) &&
|
||||
!zip->entry.uncomp_size) {
|
||||
/* Set DOS Subdirectory attribute bit. */
|
||||
zip->entry.external_attr |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
|
||||
@ -1372,11 +1415,12 @@ int zip_entry_close(struct zip_t *zip) {
|
||||
}
|
||||
|
||||
pzip->m_total_files++;
|
||||
pzip->m_archive_size = zip->entry.offset;
|
||||
pzip->m_archive_size = zip->entry.dir_offset;
|
||||
|
||||
cleanup:
|
||||
if (zip) {
|
||||
zip->entry.m_time = 0;
|
||||
zip->entry.index = -1;
|
||||
CLEANUP(zip->entry.name);
|
||||
}
|
||||
return err;
|
||||
@ -1387,7 +1431,6 @@ const char *zip_entry_name(struct zip_t *zip) {
|
||||
// zip_t handler is not initialized
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zip->entry.name;
|
||||
}
|
||||
|
||||
@ -1401,6 +1444,7 @@ ssize_t zip_entry_index(struct zip_t *zip) {
|
||||
}
|
||||
|
||||
int zip_entry_isdir(struct zip_t *zip) {
|
||||
mz_uint16 entrylen;
|
||||
if (!zip) {
|
||||
// zip_t handler is not initialized
|
||||
return ZIP_ENOINIT;
|
||||
@ -1411,8 +1455,8 @@ int zip_entry_isdir(struct zip_t *zip) {
|
||||
return ZIP_EINVIDX;
|
||||
}
|
||||
|
||||
return (int)mz_zip_reader_is_file_a_directory(&zip->archive,
|
||||
(mz_uint)zip->entry.index);
|
||||
entrylen = (mz_uint16)strlen(zip->entry.name);
|
||||
return ISSLASH(zip->entry.name[entrylen - 1]);
|
||||
}
|
||||
|
||||
unsigned long long zip_entry_size(struct zip_t *zip) {
|
||||
@ -1431,6 +1475,14 @@ unsigned int zip_entry_crc32(struct zip_t *zip) {
|
||||
return zip ? zip->entry.uncomp_crc32 : 0;
|
||||
}
|
||||
|
||||
unsigned long long zip_entry_dir_offset(struct zip_t *zip) {
|
||||
return zip ? zip->entry.dir_offset : 0;
|
||||
}
|
||||
|
||||
unsigned long long zip_entry_header_offset(struct zip_t *zip) {
|
||||
return zip ? zip->entry.header_offset : 0;
|
||||
}
|
||||
|
||||
int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
|
||||
mz_uint level;
|
||||
mz_zip_archive *pzip = NULL;
|
||||
@ -1449,12 +1501,12 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
|
||||
|
||||
level = zip->level & 0xF;
|
||||
if (!level) {
|
||||
if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf,
|
||||
if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.dir_offset, buf,
|
||||
bufsize) != bufsize)) {
|
||||
// Cannot write buffer
|
||||
return ZIP_EWRTENT;
|
||||
}
|
||||
zip->entry.offset += bufsize;
|
||||
zip->entry.dir_offset += bufsize;
|
||||
zip->entry.comp_size += bufsize;
|
||||
} else {
|
||||
status = tdefl_compress_buffer(&(zip->entry.comp), buf, bufsize,
|
||||
@ -1836,6 +1888,93 @@ void zip_stream_close(struct zip_t *zip) {
|
||||
}
|
||||
}
|
||||
|
||||
struct zip_t *zip_cstream_open(FILE *stream, int level, char mode) {
|
||||
int errnum = 0;
|
||||
return zip_cstream_openwitherror(stream, level, mode, &errnum);
|
||||
}
|
||||
|
||||
struct zip_t *zip_cstream_openwitherror(FILE *stream, int level, char mode,
|
||||
int *errnum) {
|
||||
struct zip_t *zip = NULL;
|
||||
*errnum = 0;
|
||||
if (!stream) {
|
||||
// zip archive stream is NULL
|
||||
*errnum = ZIP_ENOFILE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (level < 0)
|
||||
level = MZ_DEFAULT_LEVEL;
|
||||
if ((level & 0xF) > MZ_UBER_COMPRESSION) {
|
||||
// Wrong compression level
|
||||
*errnum = ZIP_EINVLVL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
|
||||
if (!zip) {
|
||||
// out of memory
|
||||
*errnum = ZIP_EOOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
zip->level = (mz_uint)level;
|
||||
switch (mode) {
|
||||
case 'w':
|
||||
// Create a new archive.
|
||||
if (!mz_zip_writer_init_cfile(&(zip->archive), stream,
|
||||
MZ_ZIP_FLAG_WRITE_ZIP64)) {
|
||||
// Cannot initialize zip_archive writer
|
||||
*errnum = ZIP_EWINIT;
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (!mz_zip_reader_init_cfile(
|
||||
&(zip->archive), stream, 0,
|
||||
zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
|
||||
// An archive file does not exist or cannot initialize
|
||||
// zip_archive reader
|
||||
*errnum = ZIP_ERINIT;
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'd':
|
||||
if (!mz_zip_reader_init_cfile(
|
||||
&(zip->archive), stream, 0,
|
||||
zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
|
||||
// An archive file does not exist or cannot initialize
|
||||
// zip_archive reader
|
||||
*errnum = ZIP_ERINIT;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((mode == 'a' || mode == 'd')) {
|
||||
if (!mz_zip_writer_init_from_reader_v2_noreopen(&(zip->archive), NULL,
|
||||
0)) {
|
||||
*errnum = ZIP_EWRINIT;
|
||||
mz_zip_reader_end(&(zip->archive));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*errnum = ZIP_EINVMODE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return zip;
|
||||
|
||||
cleanup:
|
||||
CLEANUP(zip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void zip_cstream_close(struct zip_t *zip) { zip_close(zip); }
|
||||
|
||||
int zip_create(const char *zipname, const char *filenames[], size_t len) {
|
||||
int err = 0;
|
||||
size_t i;
|
||||
|
63
thirdparty/zip/zip.h
vendored
63
thirdparty/zip/zip.h
vendored
@ -13,6 +13,7 @@
|
||||
#define ZIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@ -283,6 +284,25 @@ extern ZIP_EXPORT unsigned long long zip_entry_comp_size(struct zip_t *zip);
|
||||
*/
|
||||
extern ZIP_EXPORT unsigned int zip_entry_crc32(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Returns byte offset of the current zip entry
|
||||
* in the archive's central directory.
|
||||
*
|
||||
* @param zip zip archive handler.
|
||||
*
|
||||
* @return the offset in bytes.
|
||||
*/
|
||||
extern ZIP_EXPORT unsigned long long zip_entry_dir_offset(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Returns the current zip entry's local header file offset in bytes.
|
||||
*
|
||||
* @param zip zip archive handler.
|
||||
*
|
||||
* @return the entry's local header file offset in bytes.
|
||||
*/
|
||||
extern ZIP_EXPORT unsigned long long zip_entry_header_offset(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Compresses an input buffer for the current zip entry.
|
||||
*
|
||||
@ -481,6 +501,49 @@ extern ZIP_EXPORT ssize_t zip_stream_copy(struct zip_t *zip, void **buf,
|
||||
*/
|
||||
extern ZIP_EXPORT void zip_stream_close(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Opens zip archive from existing FILE stream with compression level using the
|
||||
* given mode. The stream will not be closed when calling zip_close.
|
||||
*
|
||||
* @param stream C FILE stream.
|
||||
* @param level compression level (0-9 are the standard zlib-style levels).
|
||||
* @param mode file access mode. This mode should be equivalent to the mode
|
||||
* provided when opening the file.
|
||||
* - 'r': opens a file for reading/extracting (the file must exists).
|
||||
* - 'w': creates an empty file for writing.
|
||||
* - 'a': appends to an existing archive.
|
||||
*
|
||||
* @return the zip archive handler or NULL on error
|
||||
*/
|
||||
extern ZIP_EXPORT struct zip_t *zip_cstream_open(FILE *stream, int level,
|
||||
char mode);
|
||||
|
||||
/**
|
||||
* Opens zip archive from existing FILE stream with compression level using the
|
||||
* given mode. The function additionally returns @param errnum - The stream will
|
||||
* not be closed when calling zip_close.
|
||||
*
|
||||
* @param stream C FILE stream.
|
||||
* @param level compression level (0-9 are the standard zlib-style levels).
|
||||
* @param mode file access mode.
|
||||
* - 'r': opens a file for reading/extracting (the file must exists).
|
||||
* - 'w': creates an empty file for writing.
|
||||
* - 'a': appends to an existing archive.
|
||||
* @param errnum 0 on success, negative number (< 0) on error.
|
||||
*
|
||||
* @return the zip archive handler or NULL on error
|
||||
*/
|
||||
extern ZIP_EXPORT struct zip_t *
|
||||
zip_cstream_openwitherror(FILE *stream, int level, char mode, int *errnum);
|
||||
|
||||
/**
|
||||
* Closes the zip archive, releases resources - always finalize.
|
||||
* This function is an alias for zip_close function.
|
||||
*
|
||||
* @param zip zip archive handler.
|
||||
*/
|
||||
extern ZIP_EXPORT void zip_cstream_close(struct zip_t *zip);
|
||||
|
||||
/**
|
||||
* Creates a new archive and puts files into a single zip archive.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user