Skip to content

Commit

Permalink
Split compat layer into different source files #806
Browse files Browse the repository at this point in the history
  • Loading branch information
nmoinvaz committed Oct 30, 2024
1 parent cc14474 commit 7df56f7
Show file tree
Hide file tree
Showing 14 changed files with 2,035 additions and 1,818 deletions.
26 changes: 9 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -617,27 +617,18 @@ endif()
if(MZ_COMPAT)
set(SOVERSION "1")

set(FILE_H "ioapi.h")
set(MZ_COMPAT_FILE "MZ_COMPAT_IOAPI")
configure_file(mz_compat_shim.h.in ioapi.h)

set(FILE_H "zip.h")
set(MZ_COMPAT_FILE "MZ_COMPAT_ZIP")
configure_file(mz_compat_shim.h.in zip.h)

set(FILE_H "unzip.h")
set(MZ_COMPAT_FILE "MZ_COMPAT_UNZIP")
configure_file(mz_compat_shim.h.in unzip.h)
list(APPEND MINIZIP_SRC
compat/ioapi.c
compat/unzip.c
compat/zip.c)
list(APPEND MINIZIP_HDR
compat/ioapi.h
compat/unzip.h
compat/zip.h)

if(MZ_COMPAT_VERSION)
list(APPEND MINIZIP_DEF -DMZ_COMPAT_VERSION=${MZ_COMPAT_VERSION})
endif()

list(APPEND MINIZIP_SRC mz_compat.c)
list(APPEND MINIZIP_HDR mz_compat.h
${CMAKE_CURRENT_BINARY_DIR}/ioapi.h
${CMAKE_CURRENT_BINARY_DIR}/zip.h
${CMAKE_CURRENT_BINARY_DIR}/unzip.h)
endif()

# Detect available sanitizers
Expand Down Expand Up @@ -709,6 +700,7 @@ target_include_directories(${MINIZIP_TARGET} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
if(MZ_COMPAT)
target_include_directories(${MINIZIP_TARGET} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/compat/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
endif()

Expand Down
83 changes: 83 additions & 0 deletions compat/crypt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* crypt.h -- base code for crypt/uncrypt ZIPfile
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
This code is a modified version of crypting code in Infozip distribution
The encryption/decryption parts of this source code (as opposed to the
non-echoing password parts) were originally written in Europe. The
whole source package can be freely distributed, including from the USA.
(Prior to January 2000, re-export from the US was a violation of US law.)
This encryption code is a direct transcription of the algorithm from
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
If you don't need crypting in your application, just define symbols
NOCRYPT and NOUNCRYPT.
This code support the "Traditional PKWARE Encryption".
The new AES encryption added on Zip format by Winzip (see the page
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
Encryption is not supported.
*/

#ifndef _ZLIB_H
# if (ZLIB_VERNUM < 0x1270)
typedef unsigned long z_crc_t;
# else
typedef uint32_t z_crc_t;
# endif
#endif

#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))

/***************************************************************************/
/* Return the next byte in the pseudo-random sequence */

static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */

(void)pcrc_32_tab;
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
}

/***************************************************************************/
/* Update the encryption keys with the next byte of plain text */

static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) {
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
{
register int keyshift = (int)((*(pkeys+1)) >> 24);
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
}
return c;
}


/***************************************************************************/
/* Initialize the encryption keys and the random header according to the password. */

static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
while (*passwd != '\0') {
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
passwd++;
}
}

#define zdecode(pkeys,pcrc_32_tab,c) \
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))

#define zencode(pkeys,pcrc_32_tab,c,t) \
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))
263 changes: 263 additions & 0 deletions compat/ioapi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
#include "mz.h"
#include "mz_strm.h"
#include "mz_strm_mem.h"

#include "ioapi.h"

typedef struct mz_stream_ioapi_s {
mz_stream stream;
void *handle;
zlib_filefunc_def filefunc;
zlib_filefunc64_def filefunc64;
} mz_stream_ioapi;

/***************************************************************************/

static int32_t mz_stream_ioapi_open(void *stream, const char *path, int32_t mode);
static int32_t mz_stream_ioapi_is_open(void *stream);
static int32_t mz_stream_ioapi_read(void *stream, void *buf, int32_t size);
static int32_t mz_stream_ioapi_write(void *stream, const void *buf, int32_t size);
static int64_t mz_stream_ioapi_tell(void *stream);
static int32_t mz_stream_ioapi_seek(void *stream, int64_t offset, int32_t origin);
static int32_t mz_stream_ioapi_close(void *stream);
static int32_t mz_stream_ioapi_error(void *stream);

/***************************************************************************/

static mz_stream_vtbl mz_stream_ioapi_vtbl = {
mz_stream_ioapi_open,
mz_stream_ioapi_is_open,
mz_stream_ioapi_read,
mz_stream_ioapi_write,
mz_stream_ioapi_tell,
mz_stream_ioapi_seek,
mz_stream_ioapi_close,
mz_stream_ioapi_error,
mz_stream_ioapi_create,
mz_stream_ioapi_delete,
NULL,
NULL
};

/***************************************************************************/

static int32_t mz_stream_ioapi_open(void *stream, const char *path, int32_t mode) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
int32_t ioapi_mode = 0;

if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ)
ioapi_mode = ZLIB_FILEFUNC_MODE_READ;
else if (mode & MZ_OPEN_MODE_APPEND)
ioapi_mode = ZLIB_FILEFUNC_MODE_EXISTING;
else if (mode & MZ_OPEN_MODE_CREATE)
ioapi_mode = ZLIB_FILEFUNC_MODE_CREATE;
else
return MZ_OPEN_ERROR;

if (ioapi->filefunc64.zopen64_file)
ioapi->handle = ioapi->filefunc64.zopen64_file(ioapi->filefunc64.opaque, path, ioapi_mode);
else if (ioapi->filefunc.zopen_file)
ioapi->handle = ioapi->filefunc.zopen_file(ioapi->filefunc.opaque, path, ioapi_mode);

if (!ioapi->handle)
return MZ_PARAM_ERROR;

return MZ_OK;
}

static int32_t mz_stream_ioapi_is_open(void *stream) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
if (!ioapi->handle)
return MZ_OPEN_ERROR;
return MZ_OK;
}

static int32_t mz_stream_ioapi_read(void *stream, void *buf, int32_t size) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
read_file_func zread = NULL;
void *opaque = NULL;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc64.zread_file) {
zread = ioapi->filefunc64.zread_file;
opaque = ioapi->filefunc64.opaque;
} else if (ioapi->filefunc.zread_file) {
zread = ioapi->filefunc.zread_file;
opaque = ioapi->filefunc.opaque;
} else
return MZ_PARAM_ERROR;

return (int32_t)zread(opaque, ioapi->handle, buf, size);
}

static int32_t mz_stream_ioapi_write(void *stream, const void *buf, int32_t size) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
write_file_func zwrite = NULL;
int32_t written = 0;
void *opaque = NULL;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc64.zwrite_file) {
zwrite = ioapi->filefunc64.zwrite_file;
opaque = ioapi->filefunc64.opaque;
} else if (ioapi->filefunc.zwrite_file) {
zwrite = ioapi->filefunc.zwrite_file;
opaque = ioapi->filefunc.opaque;
} else
return MZ_PARAM_ERROR;

written = (int32_t)zwrite(opaque, ioapi->handle, buf, size);
return written;
}

static int64_t mz_stream_ioapi_tell(void *stream) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc64.ztell64_file)
return ioapi->filefunc64.ztell64_file(ioapi->filefunc64.opaque, ioapi->handle);
else if (ioapi->filefunc.ztell_file)
return ioapi->filefunc.ztell_file(ioapi->filefunc.opaque, ioapi->handle);

return MZ_INTERNAL_ERROR;
}

static int32_t mz_stream_ioapi_seek(void *stream, int64_t offset, int32_t origin) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc64.zseek64_file) {
if (ioapi->filefunc64.zseek64_file(ioapi->filefunc64.opaque, ioapi->handle, offset, origin) != 0)
return MZ_INTERNAL_ERROR;
} else if (ioapi->filefunc.zseek_file) {
if (ioapi->filefunc.zseek_file(ioapi->filefunc.opaque, ioapi->handle, (int32_t)offset, origin) != 0)
return MZ_INTERNAL_ERROR;
} else
return MZ_PARAM_ERROR;

return MZ_OK;
}

static int32_t mz_stream_ioapi_close(void *stream) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
close_file_func zclose = NULL;
void *opaque = NULL;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc.zclose_file) {
zclose = ioapi->filefunc.zclose_file;
opaque = ioapi->filefunc.opaque;
} else if (ioapi->filefunc64.zclose_file) {
zclose = ioapi->filefunc64.zclose_file;
opaque = ioapi->filefunc64.opaque;
} else
return MZ_PARAM_ERROR;

if (zclose(opaque, ioapi->handle) != 0)
return MZ_CLOSE_ERROR;
ioapi->handle = NULL;
return MZ_OK;
}

static int32_t mz_stream_ioapi_error(void *stream) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
testerror_file_func zerror = NULL;
void *opaque = NULL;

if (mz_stream_ioapi_is_open(stream) != MZ_OK)
return MZ_OPEN_ERROR;

if (ioapi->filefunc.zerror_file) {
zerror = ioapi->filefunc.zerror_file;
opaque = ioapi->filefunc.opaque;
} else if (ioapi->filefunc64.zerror_file) {
zerror = ioapi->filefunc64.zerror_file;
opaque = ioapi->filefunc64.opaque;
} else
return MZ_PARAM_ERROR;

return zerror(opaque, ioapi->handle);
}

int32_t mz_stream_ioapi_set_filefunc(void *stream, zlib_filefunc_def *filefunc) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
memcpy(&ioapi->filefunc, filefunc, sizeof(zlib_filefunc_def));
return MZ_OK;
}

int32_t mz_stream_ioapi_set_filefunc64(void *stream, zlib_filefunc64_def *filefunc) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream;
memcpy(&ioapi->filefunc64, filefunc, sizeof(zlib_filefunc64_def));
return MZ_OK;
}

void *mz_stream_ioapi_create(void) {
mz_stream_ioapi *ioapi = (mz_stream_ioapi *)calloc(1, sizeof(mz_stream_ioapi));
if (ioapi)
ioapi->stream.vtbl = &mz_stream_ioapi_vtbl;
return ioapi;
}

void mz_stream_ioapi_delete(void **stream) {
mz_stream_ioapi *ioapi = NULL;
if (!stream)
return;
ioapi = (mz_stream_ioapi *)*stream;
if (ioapi)
free(ioapi);
*stream = NULL;
}

/***************************************************************************/

void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) {
/* For 32-bit file support only, compile with MZ_FILE32_API */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def));
}

void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def) {
/* All mz_stream_os_* support large files if compilation supports it */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def) {
/* Handled by mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def));
}

void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def) {
/* Automatically supported in mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def) {
/* Automatically supported in mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

/* NOTE: fill_win32_filefunc64W is no longer necessary since wide-character
support is automatically handled by the underlying os stream. Do not
pass wide-characters to zipOpen or unzOpen. */

void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def) {
/* Use opaque to indicate which stream interface to create */
if (pzlib_filefunc_def) {
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def));
pzlib_filefunc_def->opaque = mz_stream_mem_get_interface();
}
}
Loading

0 comments on commit 7df56f7

Please sign in to comment.