Skip to content

Commit

Permalink
Split compat layer into different source files
Browse files Browse the repository at this point in the history
  • Loading branch information
nmoinvaz committed Oct 30, 2024
1 parent edd7adf commit 887d6cc
Show file tree
Hide file tree
Showing 14 changed files with 2,034 additions and 1,416 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) {

Check warning on line 41 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L41

Added line #L41 was not covered by tests
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);

Check warning on line 48 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L47-L48

Added lines #L47 - L48 were not covered by tests
}

/***************************************************************************/
/* 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;

Check warning on line 57 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L54-L57

Added lines #L54 - L57 were not covered by tests
{
register int keyshift = (int)((*(pkeys+1)) >> 24);
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);

Check warning on line 60 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L59-L60

Added lines #L59 - L60 were not covered by tests
}
return c;

Check warning on line 62 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L62

Added line #L62 was not covered by tests
}


/***************************************************************************/
/* 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;

Check warning on line 72 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L69-L72

Added lines #L69 - L72 were not covered by tests
while (*passwd != '\0') {
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
passwd++;

Check warning on line 75 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L74-L75

Added lines #L74 - L75 were not covered by tests
}
}

Check warning on line 77 in compat/crypt.h

View check run for this annotation

Codecov / codecov/patch

compat/crypt.h#L77

Added line #L77 was not covered by tests

#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;

Check warning on line 51 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L51

Added line #L51 was not covered by tests
else if (mode & MZ_OPEN_MODE_CREATE)
ioapi_mode = ZLIB_FILEFUNC_MODE_CREATE;

Check warning on line 53 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L53

Added line #L53 was not covered by tests
else
return MZ_OPEN_ERROR;

Check warning on line 55 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L55

Added line #L55 was not covered by tests

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;

Check warning on line 63 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L63

Added line #L63 was not covered by tests

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;

Check warning on line 71 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L71

Added line #L71 was not covered by tests
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;

Check warning on line 81 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L81

Added line #L81 was not covered by tests

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;

Check warning on line 90 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L90

Added line #L90 was not covered by tests

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;

Check warning on line 99 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L95-L99

Added lines #L95 - L99 were not covered by tests

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

Check warning on line 102 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L102

Added line #L102 was not covered by tests

if (ioapi->filefunc64.zwrite_file) {
zwrite = ioapi->filefunc64.zwrite_file;
opaque = ioapi->filefunc64.opaque;

Check warning on line 106 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L105-L106

Added lines #L105 - L106 were not covered by tests
} else if (ioapi->filefunc.zwrite_file) {
zwrite = ioapi->filefunc.zwrite_file;
opaque = ioapi->filefunc.opaque;
} else
return MZ_PARAM_ERROR;

Check warning on line 111 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L108-L111

Added lines #L108 - L111 were not covered by tests

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

Check warning on line 115 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L113-L115

Added lines #L113 - L115 were not covered by tests

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;

Check warning on line 121 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L121

Added line #L121 was not covered by tests

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;

Check warning on line 128 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L128

Added line #L128 was not covered by tests
}

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;

Check warning on line 135 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L135

Added line #L135 was not covered by tests

if (ioapi->filefunc64.zseek64_file) {
if (ioapi->filefunc64.zseek64_file(ioapi->filefunc64.opaque, ioapi->handle, offset, origin) != 0)
return MZ_INTERNAL_ERROR;

Check warning on line 139 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L139

Added line #L139 was not covered by tests
} 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;

Check warning on line 142 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L142

Added line #L142 was not covered by tests
} else
return MZ_PARAM_ERROR;

Check warning on line 144 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L144

Added line #L144 was not covered by tests

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;

Check warning on line 155 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L155

Added line #L155 was not covered by tests

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;

Check warning on line 164 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L164

Added line #L164 was not covered by tests

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

Check warning on line 167 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L167

Added line #L167 was not covered by tests
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;

Check warning on line 175 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L172-L175

Added lines #L172 - L175 were not covered by tests

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

Check warning on line 178 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L178

Added line #L178 was not covered by tests

if (ioapi->filefunc.zerror_file) {
zerror = ioapi->filefunc.zerror_file;
opaque = ioapi->filefunc.opaque;

Check warning on line 182 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L181-L182

Added lines #L181 - L182 were not covered by tests
} else if (ioapi->filefunc64.zerror_file) {
zerror = ioapi->filefunc64.zerror_file;
opaque = ioapi->filefunc64.opaque;
} else
return MZ_PARAM_ERROR;

Check warning on line 187 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L184-L187

Added lines #L184 - L187 were not covered by tests

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

Check warning on line 190 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L189-L190

Added lines #L189 - L190 were not covered by tests

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;

Check warning on line 214 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L214

Added line #L214 was not covered by tests
ioapi = (mz_stream_ioapi *)*stream;
if (ioapi)
free(ioapi);
*stream = NULL;
}

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

void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) {

Check warning on line 223 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L223

Added line #L223 was not covered by tests
/* For 32-bit file support only, compile with MZ_FILE32_API */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def));
}

Check warning on line 227 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L226-L227

Added lines #L226 - L227 were not covered by tests

void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def) {

Check warning on line 229 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L229

Added line #L229 was not covered by tests
/* All mz_stream_os_* support large files if compilation supports it */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

Check warning on line 233 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L232-L233

Added lines #L232 - L233 were not covered by tests

void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def) {

Check warning on line 235 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L235

Added line #L235 was not covered by tests
/* Handled by mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def));
}

Check warning on line 239 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L238-L239

Added lines #L238 - L239 were not covered by tests

void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def) {

Check warning on line 241 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L241

Added line #L241 was not covered by tests
/* Automatically supported in mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

Check warning on line 245 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L244-L245

Added lines #L244 - L245 were not covered by tests

void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def) {

Check warning on line 247 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L247

Added line #L247 was not covered by tests
/* Automatically supported in mz_stream_os_win32 */
if (pzlib_filefunc_def)
memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def));
}

Check warning on line 251 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L250-L251

Added lines #L250 - L251 were not covered by tests

/* 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) {

Check warning on line 257 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L257

Added line #L257 was not covered by tests
/* 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();
}
}

Check warning on line 263 in compat/ioapi.c

View check run for this annotation

Codecov / codecov/patch

compat/ioapi.c#L260-L263

Added lines #L260 - L263 were not covered by tests
Loading

0 comments on commit 887d6cc

Please sign in to comment.