From 16978b4606ae832298ada2f8e3c471923b2c1a35 Mon Sep 17 00:00:00 2001 From: Gianluca Bertani Date: Thu, 20 Jun 2013 00:37:34 +0200 Subject: [PATCH] Updated MiniZip library to Nathan Moinvaziri version (also fixed bug in zip.c that was causing hangs when writing with no compression) --- MiniZip/crypt.h | 0 MiniZip/ioapi.c | 253 ++- MiniZip/ioapi.h | 156 +- MiniZip/mztools.c | 281 --- MiniZip/mztools.h | 31 - MiniZip/unzip.c | 2674 +++++++++++----------- MiniZip/unzip.h | 446 ++-- MiniZip/zip.c | 2678 ++++++++++++----------- MiniZip/zip.h | 360 +-- Objective-Zip.xcodeproj/project.pbxproj | 6 - Objective-Zip/ZipFile.m | 2 +- 11 files changed, 3128 insertions(+), 3759 deletions(-) mode change 100644 => 100755 MiniZip/crypt.h mode change 100644 => 100755 MiniZip/ioapi.c mode change 100644 => 100755 MiniZip/ioapi.h delete mode 100644 MiniZip/mztools.c delete mode 100644 MiniZip/mztools.h mode change 100644 => 100755 MiniZip/unzip.c mode change 100644 => 100755 MiniZip/unzip.h mode change 100644 => 100755 MiniZip/zip.c mode change 100644 => 100755 MiniZip/zip.h diff --git a/MiniZip/crypt.h b/MiniZip/crypt.h old mode 100644 new mode 100755 diff --git a/MiniZip/ioapi.c b/MiniZip/ioapi.c old mode 100644 new mode 100755 index 01a8c02..8e8c33e --- a/MiniZip/ioapi.c +++ b/MiniZip/ioapi.c @@ -1,74 +1,91 @@ /* ioapi.h -- IO base function header for compress/uncompress .zip part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - For more info read MiniZip_info.txt + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + For more info read MiniZip_info.txt */ -#if (defined(_WIN32)) - #define _CRT_SECURE_NO_WARNINGS -#endif +#include +#include #include "ioapi.h" +#if (defined(_WIN32)) + #include + #define snprintf _snprintf + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif +#endif + #if defined(__APPLE__) || defined(IOAPI_NO_64) // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions -#define FOPEN64(filename, mode) fopen(filename, mode) -#define FTELLO64(stream) ftello(stream) -#define FSEEKO64(stream, offset, origin) fseeko(stream, offset, origin) +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) #else -#define FOPEN64(filename, mode) fopen64(filename, mode) -#define FTELLO64(stream) ftello64(stream) -#define FSEEKO64(stream, offset, origin) fseeko64(stream, offset, origin) +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif +#ifndef SEEK_END +#define SEEK_END 2 +#endif +#ifndef SEEK_SET +#define SEEK_SET 0 #endif voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) { if (pfilefunc->zfile_func64.zopen64_file != NULL) return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); - else - { - return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); - } + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); +} + +voidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode)) +{ + if (pfilefunc->zfile_func64.zopendisk64_file != NULL) + return (*(pfilefunc->zfile_func64.zopendisk64_file)) (pfilefunc->zfile_func64.opaque,filestream,number_disk,mode); + return (*(pfilefunc->zopendisk32_file))(pfilefunc->zfile_func64.opaque,filestream,number_disk,mode); } long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) { + uLong offsetTruncated; if (pfilefunc->zfile_func64.zseek64_file != NULL) return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); - else - { - uLong offsetTruncated = (uLong)offset; - if (offsetTruncated != offset) - return -1; - else - return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); - } + offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); } ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) { + uLong tell_uLong; if (pfilefunc->zfile_func64.zseek64_file != NULL) return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); - else - { - uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); - if ((tell_uLong) == ((uLong)-1)) - return (ZPOS64_T)-1; - else - return tell_uLong; - } + tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == 0xffffffff) + return (ZPOS64_T)-1; + return tell_uLong; } void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) { p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zfile_func64.zopendisk64_file = NULL; p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zopendisk32_file = p_filefunc32->zopendisk_file; p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; @@ -81,8 +98,6 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; } - - static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); @@ -91,6 +106,27 @@ static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPO static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); +typedef struct +{ + FILE *file; + int filenameLength; + void *filename; +} FILE_IOPOSIX; + + +static voidpf file_build_ioposix(FILE *file, const char *filename) +{ + FILE_IOPOSIX *ioposix = NULL; + if (file == NULL) + return NULL; + ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX)); + ioposix->file = file; + ioposix->filenameLength = strlen(filename) + 1; + ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char)); + strncpy(ioposix->filename, filename, ioposix->filenameLength); + return (voidpf)ioposix; +} + static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) { FILE* file = NULL; @@ -104,8 +140,11 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in if (mode & ZLIB_FILEFUNC_MODE_CREATE) mode_fopen = "wb"; - if ((filename!=NULL) && (mode_fopen != NULL)) + if ((filename != NULL) && (mode_fopen != NULL)) + { file = fopen(filename, mode_fopen); + return file_build_ioposix(file, filename); + } return file; } @@ -122,85 +161,164 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, if (mode & ZLIB_FILEFUNC_MODE_CREATE) mode_fopen = "wb"; - if ((filename!=NULL) && (mode_fopen != NULL)) - file = FOPEN64((const char*)filename, mode_fopen); + if ((filename != NULL) && (mode_fopen != NULL)) + { + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file_build_ioposix(file, (const char*)filename); + } return file; } +static voidpf ZCALLBACK fopendisk64_file_func (voidpf opaque, voidpf stream, int number_disk, int mode) +{ + FILE_IOPOSIX *ioposix = NULL; + char *diskFilename = NULL; + voidpf ret = NULL; + int i = 0; + + if (stream == NULL) + return NULL; + ioposix = (FILE_IOPOSIX*)stream; + diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char)); + strncpy(diskFilename, ioposix->filename, ioposix->filenameLength); + for (i = ioposix->filenameLength - 1; i >= 0; i -= 1) + { + if (diskFilename[i] != '.') + continue; + snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02d", number_disk + 1); + break; + } + if (i >= 0) + ret = fopen64_file_func(opaque, diskFilename, mode); + free(diskFilename); + return ret; +} + +static voidpf ZCALLBACK fopendisk_file_func (voidpf opaque, voidpf stream, int number_disk, int mode) +{ + FILE_IOPOSIX *ioposix = NULL; + char *diskFilename = NULL; + voidpf ret = NULL; + int i = 0; + + if (stream == NULL) + return NULL; + ioposix = (FILE_IOPOSIX*)stream; + diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char)); + strncpy(diskFilename, ioposix->filename, ioposix->filenameLength); + for (i = ioposix->filenameLength - 1; i >= 0; i -= 1) + { + if (diskFilename[i] != '.') + continue; + snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02d", number_disk + 1); + break; + } + if (i >= 0) + ret = fopen_file_func(opaque, diskFilename, mode); + free(diskFilename); + return ret; +} static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) { + FILE_IOPOSIX *ioposix = NULL; uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + if (stream == NULL) + return -1; + ioposix = (FILE_IOPOSIX*)stream; + ret = (uLong)fread(buf, 1, (size_t)size, ioposix->file); return ret; } static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) { + FILE_IOPOSIX *ioposix = NULL; uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + if (stream == NULL) + return -1; + ioposix = (FILE_IOPOSIX*)stream; + ret = (uLong)fwrite(buf, 1, (size_t)size, ioposix->file); return ret; } static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) { - long ret; - ret = ftell((FILE *)stream); + FILE_IOPOSIX *ioposix = NULL; + long ret = -1; + if (stream == NULL) + return ret; + ioposix = (FILE_IOPOSIX*)stream; + ret = ftell(ioposix->file); return ret; } - static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) { - ZPOS64_T ret; - ret = FTELLO64((FILE *)stream); + FILE_IOPOSIX *ioposix = NULL; + ZPOS64_T ret = -1; + if (stream == NULL) + return ret; + ioposix = (FILE_IOPOSIX*)stream; + ret = FTELLO_FUNC(ioposix->file); return ret; } static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) { - int fseek_origin=0; + FILE_IOPOSIX *ioposix = NULL; + int fseek_origin = 0; long ret; + + if (stream == NULL) + return -1; + ioposix = (FILE_IOPOSIX*)stream; + switch (origin) { - case ZLIB_FILEFUNC_SEEK_CUR : + case ZLIB_FILEFUNC_SEEK_CUR: fseek_origin = SEEK_CUR; break; - case ZLIB_FILEFUNC_SEEK_END : + case ZLIB_FILEFUNC_SEEK_END: fseek_origin = SEEK_END; break; - case ZLIB_FILEFUNC_SEEK_SET : + case ZLIB_FILEFUNC_SEEK_SET: fseek_origin = SEEK_SET; break; default: return -1; } ret = 0; - if (fseek((FILE *)stream, offset, fseek_origin) != 0) + if (fseek(ioposix->file, offset, fseek_origin) != 0) ret = -1; return ret; } static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { - int fseek_origin=0; + FILE_IOPOSIX *ioposix = NULL; + int fseek_origin = 0; long ret; + + if (stream == NULL) + return -1; + ioposix = (FILE_IOPOSIX*)stream; + switch (origin) { - case ZLIB_FILEFUNC_SEEK_CUR : + case ZLIB_FILEFUNC_SEEK_CUR: fseek_origin = SEEK_CUR; break; - case ZLIB_FILEFUNC_SEEK_END : + case ZLIB_FILEFUNC_SEEK_END: fseek_origin = SEEK_END; break; - case ZLIB_FILEFUNC_SEEK_SET : + case ZLIB_FILEFUNC_SEEK_SET: fseek_origin = SEEK_SET; break; default: return -1; } ret = 0; - if(FSEEKO64((FILE *)stream, offset, fseek_origin) != 0) - ret = -1; + if(FSEEKO_FUNC(ioposix->file, offset, fseek_origin) != 0) + ret = -1; return ret; } @@ -208,15 +326,26 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) { - int ret; - ret = fclose((FILE *)stream); + FILE_IOPOSIX *ioposix = NULL; + int ret = -1; + if (stream == NULL) + return ret; + ioposix = (FILE_IOPOSIX*)stream; + if (ioposix->filename != NULL) + free(ioposix->filename); + ret = fclose(ioposix->file); + free(ioposix); return ret; } static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) { - int ret; - ret = ferror((FILE *)stream); + FILE_IOPOSIX *ioposix = NULL; + int ret = -1; + if (stream == NULL) + return ret; + ioposix = (FILE_IOPOSIX*)stream; + ret = ferror(ioposix->file); return ret; } @@ -224,6 +353,7 @@ void fill_fopen_filefunc (pzlib_filefunc_def) zlib_filefunc_def* pzlib_filefunc_def; { pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zopendisk_file = fopendisk_file_func; pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zwrite_file = fwrite_file_func; pzlib_filefunc_def->ztell_file = ftell_file_func; @@ -236,6 +366,7 @@ void fill_fopen_filefunc (pzlib_filefunc_def) void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) { pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zopendisk64_file = fopendisk64_file_func; pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zwrite_file = fwrite_file_func; pzlib_filefunc_def->ztell64_file = ftell64_file_func; diff --git a/MiniZip/ioapi.h b/MiniZip/ioapi.h old mode 100644 new mode 100755 index 0e5cbc3..d60bbcc --- a/MiniZip/ioapi.h +++ b/MiniZip/ioapi.h @@ -1,20 +1,20 @@ /* ioapi.h -- IO base function header for compress/uncompress .zip part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read MiniZip_info.txt - Changes + Changes - Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) - Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. - More if/def section may be needed to support other platforms - Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. - (but you should use iowin32.c for windows instead) + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) */ @@ -22,22 +22,20 @@ #define _ZLIBIOAPI64_H #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) - - // Linux needs this to support file operation on files larger then 4+GB - // But might need better if/def to select just the platforms that needs them. - - #ifndef __USE_FILE_OFFSET64 - #define __USE_FILE_OFFSET64 - #endif - #ifndef __USE_LARGEFILE64 - #define __USE_LARGEFILE64 - #endif - #ifndef _LARGEFILE64_SOURCE - #define _LARGEFILE64_SOURCE - #endif - #ifndef _FILE_OFFSET_BIT - #define _FILE_OFFSET_BIT 64 - #endif + /* Linux needs this to support file operation on files larger then 4+GB + But might need better if/def to select just the platforms that needs them. */ + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif #endif #include @@ -49,33 +47,23 @@ #define ftello64 ftell #define fseeko64 fseek #else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif #ifdef _MSC_VER - #define fopen64 fopen - #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) - #define ftello64 _ftelli64 - #define fseeko64 _fseeki64 - #else // old MSC - #define ftello64 ftell - #define fseeko64 fseek - #endif + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif #endif #endif -/* -#ifndef ZPOS64_T - #ifdef _WIN32 - #define ZPOS64_T fpos_t - #else - #include - #define ZPOS64_T uint64_t - #endif -#endif -*/ - -#ifdef HAVE_MINIZIP64_CONF_H -#include "mz64conf.h" -#endif - /* a type choosen by DEFINE */ #ifdef HAVE_64BIT_INT_CUSTOM typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; @@ -85,7 +73,6 @@ typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; typedef uint64_t ZPOS64_T; #else - #if defined(_MSC_VER) || defined(__BORLANDC__) typedef unsigned __int64 ZPOS64_T; #else @@ -94,13 +81,10 @@ typedef unsigned long long int ZPOS64_T; #endif #endif - - #ifdef __cplusplus extern "C" { #endif - #define ZLIB_FILEFUNC_SEEK_CUR (1) #define ZLIB_FILEFUNC_SEEK_END (2) #define ZLIB_FILEFUNC_SEEK_SET (0) @@ -112,19 +96,17 @@ extern "C" { #define ZLIB_FILEFUNC_MODE_EXISTING (4) #define ZLIB_FILEFUNC_MODE_CREATE (8) - #ifndef ZCALLBACK - #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) - #define ZCALLBACK CALLBACK - #else - #define ZCALLBACK - #endif + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || \ + defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif #endif - - - typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef voidpf (ZCALLBACK *opendisk_file_func) OF((voidpf opaque, voidpf stream, int number_disk, int mode)); typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); @@ -133,11 +115,11 @@ typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stre typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); - /* here is the "old" 32 bits structure structure */ typedef struct zlib_filefunc_def_s { open_file_func zopen_file; + opendisk_file_func zopendisk_file; read_file_func zread_file; write_file_func zwrite_file; tell_file_func ztell_file; @@ -150,48 +132,52 @@ typedef struct zlib_filefunc_def_s typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); +typedef voidpf (ZCALLBACK *opendisk64_file_func)OF((voidpf opaque, voidpf stream, int number_disk, int mode)); typedef struct zlib_filefunc64_def_s { - open64_file_func zopen64_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell64_file_func ztell64_file; - seek64_file_func zseek64_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; + open64_file_func zopen64_file; + opendisk64_file_func zopendisk64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; } zlib_filefunc64_def; -void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); /* now internal definition, only for zip.c and unzip.h */ typedef struct zlib_filefunc64_32_def_s { zlib_filefunc64_def zfile_func64; open_file_func zopen32_file; + opendisk_file_func zopendisk32_file; tell_file_func ztell32_file; seek_file_func zseek32_file; } zlib_filefunc64_32_def; +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) -//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) - -voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); -long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +voidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); +void fill_zlib_filefunc64_32_def_from_filefunc32 OF((zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)); -#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) -#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) -#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) #ifdef __cplusplus } diff --git a/MiniZip/mztools.c b/MiniZip/mztools.c deleted file mode 100644 index f9092e6..0000000 --- a/MiniZip/mztools.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - Additional tools for Minizip - Code: Xavier Roche '2004 - License: Same as ZLIB (www.gzip.org) -*/ - -/* Code */ -#include -#include -#include -#include "zlib.h" -#include "unzip.h" - -#define READ_8(adr) ((unsigned char)*(adr)) -#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) -#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) - -#define WRITE_8(buff, n) do { \ - *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ -} while(0) -#define WRITE_16(buff, n) do { \ - WRITE_8((unsigned char*)(buff), n); \ - WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ -} while(0) -#define WRITE_32(buff, n) do { \ - WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ - WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ -} while(0) - -extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) -const char* file; -const char* fileOut; -const char* fileOutTmp; -uLong* nRecovered; -uLong* bytesRecovered; -{ - int err = Z_OK; - FILE* fpZip = fopen(file, "rb"); - FILE* fpOut = fopen(fileOut, "wb"); - FILE* fpOutCD = fopen(fileOutTmp, "wb"); - if (fpZip != NULL && fpOut != NULL) { - int entries = 0; - uLong totalBytes = 0; - char header[30]; - char filename[256]; - char extra[1024]; - int offset = 0; - int offsetCD = 0; - while ( fread(header, 1, 30, fpZip) == 30 ) { - int currentOffset = offset; - - /* File entry */ - if (READ_32(header) == 0x04034b50) { - unsigned int version = READ_16(header + 4); - unsigned int gpflag = READ_16(header + 6); - unsigned int method = READ_16(header + 8); - unsigned int filetime = READ_16(header + 10); - unsigned int filedate = READ_16(header + 12); - unsigned int crc = READ_32(header + 14); /* crc */ - unsigned int cpsize = READ_32(header + 18); /* compressed size */ - unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ - unsigned int fnsize = READ_16(header + 26); /* file name length */ - unsigned int extsize = READ_16(header + 28); /* extra field length */ - filename[0] = extra[0] = '\0'; - - /* Header */ - if (fwrite(header, 1, 30, fpOut) == 30) { - offset += 30; - } else { - err = Z_ERRNO; - break; - } - - /* Filename */ - if (fnsize > 0) { - if (fread(filename, 1, fnsize, fpZip) == fnsize) { - if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { - offset += fnsize; - } else { - err = Z_ERRNO; - break; - } - } else { - err = Z_ERRNO; - break; - } - } else { - err = Z_STREAM_ERROR; - break; - } - - /* Extra field */ - if (extsize > 0) { - if (fread(extra, 1, extsize, fpZip) == extsize) { - if (fwrite(extra, 1, extsize, fpOut) == extsize) { - offset += extsize; - } else { - err = Z_ERRNO; - break; - } - } else { - err = Z_ERRNO; - break; - } - } - - /* Data */ - { - int dataSize = cpsize; - if (dataSize == 0) { - dataSize = uncpsize; - } - if (dataSize > 0) { - char* data = malloc(dataSize); - if (data != NULL) { - if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { - if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { - offset += dataSize; - totalBytes += dataSize; - } else { - err = Z_ERRNO; - } - } else { - err = Z_ERRNO; - } - free(data); - if (err != Z_OK) { - break; - } - } else { - err = Z_MEM_ERROR; - break; - } - } - } - - /* Central directory entry */ - { - char header[46]; - char* comment = ""; - int comsize = (int) strlen(comment); - WRITE_32(header, 0x02014b50); - WRITE_16(header + 4, version); - WRITE_16(header + 6, version); - WRITE_16(header + 8, gpflag); - WRITE_16(header + 10, method); - WRITE_16(header + 12, filetime); - WRITE_16(header + 14, filedate); - WRITE_32(header + 16, crc); - WRITE_32(header + 20, cpsize); - WRITE_32(header + 24, uncpsize); - WRITE_16(header + 28, fnsize); - WRITE_16(header + 30, extsize); - WRITE_16(header + 32, comsize); - WRITE_16(header + 34, 0); /* disk # */ - WRITE_16(header + 36, 0); /* int attrb */ - WRITE_32(header + 38, 0); /* ext attrb */ - WRITE_32(header + 42, currentOffset); - /* Header */ - if (fwrite(header, 1, 46, fpOutCD) == 46) { - offsetCD += 46; - - /* Filename */ - if (fnsize > 0) { - if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { - offsetCD += fnsize; - } else { - err = Z_ERRNO; - break; - } - } else { - err = Z_STREAM_ERROR; - break; - } - - /* Extra field */ - if (extsize > 0) { - if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { - offsetCD += extsize; - } else { - err = Z_ERRNO; - break; - } - } - - /* Comment field */ - if (comsize > 0) { - if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { - offsetCD += comsize; - } else { - err = Z_ERRNO; - break; - } - } - - - } else { - err = Z_ERRNO; - break; - } - } - - /* Success */ - entries++; - - } else { - break; - } - } - - /* Final central directory */ - { - int entriesZip = entries; - char header[22]; - char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; - int comsize = (int) strlen(comment); - if (entriesZip > 0xffff) { - entriesZip = 0xffff; - } - WRITE_32(header, 0x06054b50); - WRITE_16(header + 4, 0); /* disk # */ - WRITE_16(header + 6, 0); /* disk # */ - WRITE_16(header + 8, entriesZip); /* hack */ - WRITE_16(header + 10, entriesZip); /* hack */ - WRITE_32(header + 12, offsetCD); /* size of CD */ - WRITE_32(header + 16, offset); /* offset to CD */ - WRITE_16(header + 20, comsize); /* comment */ - - /* Header */ - if (fwrite(header, 1, 22, fpOutCD) == 22) { - - /* Comment field */ - if (comsize > 0) { - if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { - err = Z_ERRNO; - } - } - - } else { - err = Z_ERRNO; - } - } - - /* Final merge (file + central directory) */ - fclose(fpOutCD); - if (err == Z_OK) { - fpOutCD = fopen(fileOutTmp, "rb"); - if (fpOutCD != NULL) { - int nRead; - char buffer[8192]; - while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { - if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { - err = Z_ERRNO; - break; - } - } - fclose(fpOutCD); - } - } - - /* Close */ - fclose(fpZip); - fclose(fpOut); - - /* Wipe temporary file */ - (void)remove(fileOutTmp); - - /* Number of recovered entries */ - if (err == Z_OK) { - if (nRecovered != NULL) { - *nRecovered = entries; - } - if (bytesRecovered != NULL) { - *bytesRecovered = totalBytes; - } - } - } else { - err = Z_STREAM_ERROR; - } - return err; -} diff --git a/MiniZip/mztools.h b/MiniZip/mztools.h deleted file mode 100644 index 88b3459..0000000 --- a/MiniZip/mztools.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Additional tools for Minizip - Code: Xavier Roche '2004 - License: Same as ZLIB (www.gzip.org) -*/ - -#ifndef _zip_tools_H -#define _zip_tools_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#include "unzip.h" - -/* Repair a ZIP file (missing central directory) - file: file to recover - fileOut: output file after recovery - fileOutTmp: temporary file name used for recovery -*/ -extern int ZEXPORT unzRepair(const char* file, - const char* fileOut, - const char* fileOutTmp, - uLong* nRecovered, - uLong* bytesRecovered); - -#endif diff --git a/MiniZip/unzip.c b/MiniZip/unzip.c old mode 100644 new mode 100755 index 9426aec..0662bc5 --- a/MiniZip/unzip.c +++ b/MiniZip/unzip.c @@ -2,75 +2,74 @@ Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications of Unzip for Zip64 - Copyright (C) 2007-2008 Even Rouault + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault - Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read MiniZip_info.txt + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. - ------------------------------------------------------------------------------------ - Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of - compatibility with older software. The following is from the original crypt.c. - Code woven in by Terry Thorsen 1/2003. + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - 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.) + 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). + 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). - ------------------------------------------------------------------------------------ + ------------------------------------------------------------------------------------ - Changes in unzip.c + Changes in unzip.c - 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos - 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* - 2007-2008 - Even Rouault - Remove old C style function prototypes - 2007-2008 - Even Rouault - Add unzip support for ZIP64 + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 - Copyright (C) 2007-2008 Even Rouault + Copyright (C) 2007-2008 Even Rouault + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xffffffff + Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + Aug-2010 - Nathan Moinvaziri - Added PKZIP spanning support + May-2012 - Nathan Moinvaziri - Added AES encryption support + Jul-2012 - Nathan Moinvaziri - Clean up & changed unzLocateFile to support custom comparison function - Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). - Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G - should only read the compressed/uncompressed size from the Zip64 format if - the size from normal header was 0xFFFFFFFF - Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant - Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) - Patch created by Daniel Borca - - Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer - - Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson */ - #include #include #include -#ifndef NOUNCRYPT +/*#ifndef NOUNCRYPT #define NOUNCRYPT -#endif +#endif*/ #include "zlib.h" #include "unzip.h" @@ -86,26 +85,46 @@ # include #endif +#ifdef HAVE_AES +#define AES_METHOD (99) +#define AES_PWVERIFYSIZE (2) +#define AES_MAXSALTLENGTH (16) +#define AES_AUTHCODESIZE (10) +#define AES_HEADERSIZE (11) +#define AES_KEYSIZE(mode) (64 + (mode * 64)) + +#include "aes/aes.h" +#include "aes/fileenc.h" +#endif +#ifndef NOUNCRYPT +#include "crypt.h" +#endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ +#define DISKHEADERMAGIC (0x08074b50) +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x06064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x07064b50) -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif +#define SIZECENTRALDIRITEM (0x2e) +#define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */ +#define SIZEZIPLOCALHEADER (0x1e) + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) #endif - #ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) +#define UNZ_BUFSIZE (64 * 1024) #endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC @@ -115,668 +134,463 @@ # define TRYFREE(p) {if (p) free(p);} #endif -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { - ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ + ZPOS64_T offset_curfile; /* relative offset of local header 8 bytes */ + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx) */ +#ifdef HAVE_AES + uLong aes_encryption_mode; + uLong aes_compression_method; +#endif } unz_file_info64_internal; - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ +/* file_in_zip_read_info_s contain internal information about a file in zipfile */ typedef struct { - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ + Bytef *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ #ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif +#ifdef HAVE_AES + fcrypt_ctx aes_ctx; #endif - ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek */ + uLong stream_initialised; /* flag set if stream structure is initialised */ - ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read */ ZPOS64_T total_out_64; - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ - ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed; /* number of byte to be obtained after decomp */ + zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; + + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx) */ + int raw; } file_in_zip64_read_info_s; - -/* unz64_s contain internal information about the zipfile -*/ +/* unz64_s contain internal information about the zipfile */ typedef struct { zlib_filefunc64_32_def z_filefunc; - int is64bitOpenFunction; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info64 gi; /* public global information */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - ZPOS64_T num_file; /* number of the current file in the zipfile*/ - ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ - ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ - ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + voidpf filestream; /* io structure of the current zipfile */ + voidpf filestream_with_CD; /* io structure of the disk with the central directory */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + uLong number_disk; /* number of the current disk, used for spanning ZIP*/ + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info64 cur_file_info; /* public info about the current file in zip*/ - unz_file_info64_internal cur_file_info_internal; /* private info about it*/ - file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; - - int isZip64; - -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; + /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; + /* structure about the current file if we are decompressing it */ + int encrypted; /* is the current file encrypted */ + int isZip64; /* is the current file zip64 */ +#ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const unsigned long* pcrc_32_tab; -# endif +#endif } unz64_s; +/* Translate date/time from Dos format to tm_unz (readable more easily) */ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate = (ZPOS64_T)(ulDosDate>>16); -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unz64local_getByte OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); + ptm->tm_mday = (uInt)(uDate&0x1f); + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1); + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980); + ptm->tm_hour = (uInt)((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt)((ulDosDate&0x7E0)/0x20); + ptm->tm_sec = (uInt)(2*(ulDosDate&0x1f)); +} +/* Read a byte from a gz_stream; Return EOF for end of file. */ local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) { unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) + int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c,1); + if (err == 1) { *pi = (int)c; return UNZ_OK; } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } + if (ZERROR64(*pzlib_filefunc_def, filestream)) + return UNZ_ERRNO; + return UNZ_EOF; } - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unz64local_getShort OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) +local int unz64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { - uLong x ; + uLong x; int i = 0; int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((uLong)i)<<8; - if (err==UNZ_OK) + if (err == UNZ_OK) *pX = x; else *pX = 0; return err; } -local int unz64local_getLong OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) +local int unz64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { - uLong x ; + uLong x; int i = 0; int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x += ((uLong)i)<<24; - if (err==UNZ_OK) + if (err == UNZ_OK) *pX = x; else *pX = 0; return err; } -local int unz64local_getLong64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX)); - - -local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX) +local int unz64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { - ZPOS64_T x ; + ZPOS64_T x; int i = 0; int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x = (ZPOS64_T)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<24; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<32; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<40; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<48; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); x |= ((ZPOS64_T)i)<<56; - if (err==UNZ_OK) + if (err == UNZ_OK) *pX = x; else *pX = 0; return err; } -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, - const char* fileName2, - int iCaseSensitivity) - -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ +/* Locate the Central directory of a zip file (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + ZPOS64_T file_size; + ZPOS64_T back_read = 4; + ZPOS64_T max_back = 0xffff; /* maximum size of global comment */ + ZPOS64_T pos_found = 0; + uLong read_size; + ZPOS64_T read_pos; + int i; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf == NULL) + return 0; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; + file_size = ZTELL64(*pzlib_filefunc_def, filestream); - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + if (max_back > file_size) + max_back = file_size; - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; + if (back_read + BUFREADCOMMENT > max_back) + back_read = max_back; else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; + back_read += BUFREADCOMMENT; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + read_pos = file_size-back_read; + read_size = ((BUFREADCOMMENT+4) < (file_size-read_pos)) ? + (BUFREADCOMMENT+4) : (uLong)(file_size-read_pos); + + if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size) break; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + for (i = (int)read_size-3; (i--) > 0;) + if (((*(buf+i)) == (ENDHEADERMAGIC & 0xff)) && + ((*(buf+i+1)) == (ENDHEADERMAGIC >> 8 & 0xff)) && + ((*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff)) && + ((*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff))) { - uPosFound = uReadPos+i; + pos_found = read_pos+i; break; } - if (uPosFound!=0) + if (pos_found != 0) break; } TRYFREE(buf); - return uPosFound; + return pos_found; } - -/* - Locate the Central directory 64 of a zipfile (at the end, just before - the global comment) -*/ -local ZPOS64_T unz64local_SearchCentralDir64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream)); - -local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream) +/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */ +local ZPOS64_T unz64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + const ZPOS64_T endcentraloffset)); +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + const ZPOS64_T endcentraloffset) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + ZPOS64_T offset; uLong uL; - ZPOS64_T relativeOffset; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - if (uPosFound == 0) - return 0; /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR,ZLIB_FILEFUNC_SEEK_SET) != 0) return 0; - /* the signature, already checked */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + /* read locator signature */ + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; + if (uL != ZIP64ENDLOCHEADERMAGIC) return 0; - /* number of the disk with the start of the zip64 end of central directory */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) return 0; - if (uL != 0) - return 0; - /* relative offset of the zip64 end of central directory record */ - if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + if (unz64local_getLong64(pzlib_filefunc_def, filestream, &offset) != UNZ_OK) return 0; - /* total number of disks */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) return 0; - if (uL != 1) - return 0; - /* Goto end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + if (ZSEEK64(*pzlib_filefunc_def,filestream, offset,ZLIB_FILEFUNC_SEEK_SET) != 0) return 0; - /* the signature */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; + if (uL != ZIP64ENDHEADERMAGIC) return 0; - if (uL != 0x06064b50) - return 0; - - return relativeOffset; + return offset; } -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -local unzFile unzOpenInternal (const void *path, - zlib_filefunc64_32_def* pzlib_filefunc64_32_def, - int is64bitOpenFunction) +local unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, int is64bitOpenFunction) { unz64_s us; unz64_s *s; ZPOS64_T central_pos; - uLong uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; + uLong uL; + voidpf filestream = NULL; + ZPOS64_T number_entry_CD; + int err = UNZ_OK; if (unz_copyright[0]!=' ') return NULL; + us.filestream = NULL; + us.filestream_with_CD = NULL; us.z_filefunc.zseek32_file = NULL; us.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) + if (pzlib_filefunc64_32_def == NULL) fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); else us.z_filefunc = *pzlib_filefunc64_32_def; - us.is64bitOpenFunction = is64bitOpenFunction; - - - us.filestream = ZOPEN64(us.z_filefunc, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) + us.filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); + + if (us.filestream == NULL) return NULL; - central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + us.filestream_with_CD = us.filestream; + us.isZip64 = 0; + + /* Use unz64local_SearchCentralDir first. Only based on the result + is it necessary to locate the unz64local_SearchCentralDir64 */ + central_pos = unz64local_SearchCentralDir(&us.z_filefunc, us.filestream); if (central_pos) { - uLong uS; - ZPOS64_T uL64; - - us.isZip64 = 1; - - if (ZSEEK64(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; + if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; /* the signature, already checked */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* size of zip64 end of central directory record */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) - err=UNZ_ERRNO; - - /* version made by */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; - - /* version needed to extract */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; - + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; /* number of this disk */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.number_disk = uL; /* number of the disk with the start of the central directory */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - + if (unz64local_getShort(&us.z_filefunc, us.filestream,& uL) != UNZ_OK) + err = UNZ_ERRNO; + us.gi.number_disk_with_CD = uL; /* total number of entries in the central directory on this disk */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.gi.number_entry = uL; /* total number of entries in the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + number_entry_CD = uL; + if (number_entry_CD!=us.gi.number_entry) + err = UNZ_BADZIPFILE; /* size of the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.size_central_dir = uL; + /* offset of start of central directory with respect to the starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.offset_central_dir = uL; + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK) + err = UNZ_ERRNO; - /* offset of start of central directory with respect to the - starting disk number */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; + if ((err == UNZ_OK) && + ((us.gi.number_entry == 0xffff) || (us.size_central_dir == 0xffff) || (us.offset_central_dir == 0xffffffff))) + { + /* Format should be Zip64, as the central directory or file size is too large */ + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc, us.filestream, central_pos); + if (central_pos) + { + ZPOS64_T uL64; - us.gi.size_comment = 0; + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &uL64) != UNZ_OK) + err = UNZ_ERRNO; + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.number_disk) != UNZ_OK) + err = UNZ_ERRNO; + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.gi.number_disk_with_CD) != UNZ_OK) + err = UNZ_ERRNO; + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK) + err = UNZ_ERRNO; + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK) + err = UNZ_ERRNO; + if (number_entry_CD!=us.gi.number_entry) + err = UNZ_BADZIPFILE; + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK) + err = UNZ_ERRNO; + /* offset of start of central directory with respect to the starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK) + err = UNZ_ERRNO; + } + else + err = UNZ_BADZIPFILE; + } } else - { - central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; + err = UNZ_ERRNO; - us.isZip64 = 0; + if ((err == UNZ_OK) && (central_pospfile_in_zip_read!=NULL) + if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile(file); - ZCLOSE64(s->z_filefunc, s->filestream); + if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD)) + ZCLOSE64(s->z_filefunc, s->filestream); + if (s->filestream_with_CD != NULL) + ZCLOSE64(s->z_filefunc, s->filestream_with_CD); + + s->filestream = NULL; + s->filestream_with_CD = NULL; TRYFREE(s); return UNZ_OK; } - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +/* Goto to the next available disk for spanned archives */ +local int unzGoToNextDisk OF((unzFile file)); +local int unzGoToNextDisk(unzFile file) { unz64_s* s; - if (file==NULL) + file_in_zip64_read_info_s* pfile_in_zip_read_info; + int number_disk_next; + + s = (unz64_s*)file; + if (s == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; - *pglobal_info=s->gi; + pfile_in_zip_read_info = s->pfile_in_zip_read; + number_disk_next = s->number_disk; + + if ((pfile_in_zip_read_info != NULL) && (pfile_in_zip_read_info->rest_read_uncompressed > 0)) + /* We are currently reading a file and we need the next sequential disk */ + number_disk_next += 1; + else + /* Goto the disk for the current file */ + number_disk_next = s->cur_file_info.disk_num_start; + + if (number_disk_next != s->number_disk) + { + /* Switch disks */ + if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD)) + ZCLOSE64(s->z_filefunc, s->filestream); + + if (number_disk_next == s->gi.number_disk_with_CD) + { + s->filestream = s->filestream_with_CD; + } + else + { + s->filestream = ZOPENDISK64(s->z_filefunc, s->filestream_with_CD, number_disk_next, + ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); + } + + if (s->filestream == NULL) + return UNZ_ERRNO; + + s->number_disk = number_disk_next; + } + return UNZ_OK; } -extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { unz64_s* s; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; + s = (unz64_s*)file; /* to do : check if number_entry is not truncated */ pglobal_info32->number_entry = (uLong)s->gi.number_entry; pglobal_info32->size_comment = s->gi.size_comment; + pglobal_info32->number_disk_with_CD = s->gi.number_disk_with_CD; return UNZ_OK; } -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) -{ - ZPOS64_T uDate; - uDate = (ZPOS64_T)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + *pglobal_info = s->gi; + return UNZ_OK; } -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); +extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uLong comment_size) +{ + unz64_s* s; + uLong bytes_to_read = comment_size; + if (file == NULL) + return (int)UNZ_PARAMERROR; + s = (unz64_s*)file; -local int unz64local_GetCurrentFileInfoInternal (unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize) + if (bytes_to_read > s->gi.size_comment) + bytes_to_read = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream_with_CD,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (bytes_to_read>0) + { + *comment = 0; + if (ZREAD64(s->z_filefunc,s->filestream_with_CD,comment,bytes_to_read) != bytes_to_read) + return UNZ_ERRNO; + } + + if ((comment != NULL) && (comment_size > s->gi.size_comment)) + *(comment+s->gi.size_comment) = 0; + return (int)bytes_to_read; +} + +/* Get Info about the current file in the zipfile, with internal only info */ +local int unz64local_GetCurrentFileInfoInternal(unzFile file, unz_file_info64 *pfile_info, + unz_file_info64_internal *pfile_info_internal, char *filename, uLong filename_size, void *extrafield, + uLong extrafield_size, char *comment, uLong comment_size) { unz64_s* s; unz_file_info64 file_info; unz_file_info64_internal file_info_internal; - int err=UNZ_OK; + ZPOS64_T bytes_to_read; + int err = UNZ_OK; uLong uMagic; - long lSeek=0; + long lSeek = 0; + ZPOS64_T current_pos = 0; + uLong acc = 0; uLong uL; + ZPOS64_T uL64; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; + s = (unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, + s->pos_in_central_dir+s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; - /* we check the magic */ - if (err==UNZ_OK) + /* Check the magic */ + if (err == UNZ_OK) { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic!=CENTRALHEADERMAGIC) + err = UNZ_BADZIPFILE; } - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - + /* Read central directory header */ + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version_needed) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.flag) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.compression_method) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.dosDate) != UNZ_OK) + err = UNZ_ERRNO; unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.crc) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; file_info.compressed_size = uL; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; file_info.uncompressed_size = uL; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_filename) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_extra) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_comment) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.internal_fa) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.external_fa) != UNZ_OK) + err = UNZ_ERRNO; + /* Relative offset of local header */ + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uL) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - // relative offset of local header - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; + file_info.size_file_extra_internal = 0; + file_info.disk_offset = uL; file_info_internal.offset_curfile = uL; +#ifdef HAVE_AES + file_info_internal.aes_compression_method = 0; + file_info_internal.aes_encryption_mode = 0; +#endif - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) + lSeek += file_info.size_filename; + + if ((err == UNZ_OK) && (filename!=NULL)) { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; + if ((file_info.size_filename > 0) && (filename_size > 0)) + if (ZREAD64(s->z_filefunc, s->filestream_with_CD,filename, (uLong)bytes_to_read) != bytes_to_read) + err = UNZ_ERRNO; + lSeek -= (uLong)bytes_to_read; } - // Read extrafield - if ((err==UNZ_OK) && (extraField!=NULL)) + /* Read extrafield */ + if ((err == UNZ_OK) && (extrafield!=NULL)) { - ZPOS64_T uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) lSeek=0; else - err=UNZ_ERRNO; + err = UNZ_ERRNO; } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - - lSeek += file_info.size_file_extra - (uLong)uSizeRead; + if ((file_info.size_file_extra > 0) && (extrafield_size > 0)) + if (ZREAD64(s->z_filefunc, s->filestream_with_CD, extrafield, (uLong)bytes_to_read) != bytes_to_read) + err = UNZ_ERRNO; + lSeek += file_info.size_file_extra - (uLong)bytes_to_read; } else lSeek += file_info.size_file_extra; - - if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + if ((err == UNZ_OK) && (file_info.size_file_extra != 0)) { - uLong acc = 0; - - // since lSeek now points to after the extra field we need to move back - lSeek -= file_info.size_file_extra; - - if (lSeek!=0) + if (lSeek != 0) { - if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) lSeek=0; else - err=UNZ_ERRNO; + err = UNZ_ERRNO; } - while(acc < file_info.size_file_extra) + /* We are going to parse the extra field so we need to move back */ + current_pos = ZTELL64(s->z_filefunc, s->filestream_with_CD); + if (current_pos < file_info.size_file_extra) + err = UNZ_ERRNO; + current_pos -= file_info.size_file_extra; + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, current_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + while((err != UNZ_ERRNO) && (acc < file_info.size_file_extra)) { - uLong headerId; - uLong dataSize; + uLong headerid; + uLong datasize; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) - err=UNZ_ERRNO; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &headerid) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &datasize) != UNZ_OK) + err = UNZ_ERRNO; /* ZIP64 extra fields */ - if (headerId == 0x0001) + if (headerid == 0x0001) { - uLong uL; - - if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) - { - /* Relative Header offset */ - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.disk_num_start == (unsigned long)-1) - { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - } + /* Subtract size of ZIP64 field, since ZIP64 is handled internally */ + file_info.size_file_extra_internal += 2 + 2 + datasize; + if (file_info.uncompressed_size == 0xffffffff) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.uncompressed_size) != UNZ_OK) + err = UNZ_ERRNO; + } + if (file_info.compressed_size == 0xffffffff) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.compressed_size) != UNZ_OK) + err = UNZ_ERRNO; + } + if (file_info_internal.offset_curfile == 0xffffffff) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &uL64) != UNZ_OK) + err = UNZ_ERRNO; + file_info_internal.offset_curfile = uL64; + file_info.disk_offset = uL64; + } + if (file_info.disk_num_start == 0xffffffff) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK) + err = UNZ_ERRNO; + } } +#ifdef HAVE_AES + /* AES header */ + else if (headerid == 0x9901) + { + /* Subtract size of AES field, since AES is handled internally */ + file_info.size_file_extra_internal += 2 + 2 + datasize; + + /* Verify version info */ + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; + if (uL != 1) + err = UNZ_ERRNO; + if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; + if ((char)uL != 'A') + err = UNZ_ERRNO; + if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; + if ((char)uL != 'E') + err = UNZ_ERRNO; + /* Get AES encryption strength and actual compression method */ + if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; + file_info_internal.aes_encryption_mode = uL; + if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK) + err = UNZ_ERRNO; + file_info_internal.aes_compression_method = uL; + } +#endif else { - if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) - err=UNZ_ERRNO; + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,datasize, ZLIB_FILEFUNC_SEEK_CUR) != 0) + err = UNZ_ERRNO; } - acc += 2 + 2 + dataSize; + acc += 2 + 2 + datasize; } } - if ((err==UNZ_OK) && (szComment!=NULL)) + if (file_info.disk_num_start == s->gi.number_disk_with_CD) + file_info_internal.byte_before_the_zipfile = s->byte_before_the_zipfile; + else + file_info_internal.byte_before_the_zipfile = 0; + + if ((err == UNZ_OK) && (comment != NULL)) { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - /* lSeek=0 */; + if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek=0; else - err=UNZ_ERRNO; + err = UNZ_ERRNO; } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - /* lSeek += file_info.size_file_comment - uSizeRead */; + if ((file_info.size_file_comment > 0) && (comment_size > 0)) + if (ZREAD64(s->z_filefunc, s->filestream_with_CD, comment, (uLong)bytes_to_read) != bytes_to_read) + err = UNZ_ERRNO; + lSeek += file_info.size_file_comment - (uLong)bytes_to_read; } else - /* lSeek += file_info.size_file_comment */; + lSeek += file_info.size_file_comment; - if ((err==UNZ_OK) && (pfile_info!=NULL)) + if ((err == UNZ_OK) && (pfile_info!=NULL)) *pfile_info=file_info; - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + if ((err == UNZ_OK) && (pfile_info_internal!=NULL)) *pfile_info_internal=file_info_internal; return err; } - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, - unz_file_info64 * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info * pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char* comment, uLong comment_size) { - return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, - unz_file_info * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) -{ - int err; unz_file_info64 file_info64; - err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); - if (err==UNZ_OK) + int err; + + err = unz64local_GetCurrentFileInfoInternal(file, &file_info64, NULL, filename, filename_size, + extrafield, extrafield_size, comment, comment_size); + + if ((err == UNZ_OK) && (pfile_info != NULL)) { pfile_info->version = file_info64.version; pfile_info->version_needed = file_info64.version_needed; @@ -1155,7 +1007,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, pfile_info->crc = file_info64.crc; pfile_info->size_filename = file_info64.size_filename; - pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_extra = file_info64.size_file_extra - file_info64.size_file_extra_internal; pfile_info->size_file_comment = file_info64.size_file_comment; pfile_info->disk_num_start = file_info64.disk_num_start; @@ -1164,300 +1016,99 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, pfile_info->tmu_date = file_info64.tmu_date, - pfile_info->compressed_size = (uLong)file_info64.compressed_size; pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; } return err; } -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (unzFile file) + +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char* comment, uLong comment_size) { - int err=UNZ_OK; - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; + return unz64local_GetCurrentFileInfoInternal(file, pfile_info, NULL, filename, filename_size, + extrafield, extrafield_size, comment,comment_size); } -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (unzFile file) +/* Read the local header of the current zipfile. Check the coherency of the local header and info in the + end of central directory about this file store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) */ +local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar, ZPOS64_T *poffset_local_extrafield, + uInt *psize_local_extrafield) { - unz64_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) -{ - unz64_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info64 cur_file_infoSaved; - unz_file_info64_internal cur_file_info_internalSaved; - ZPOS64_T num_fileSaved; - ZPOS64_T pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo64(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - ZPOS64_T pos_in_zip_directory; // offset in file - ZPOS64_T num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) -{ - unz64_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos) -{ - unz64_file_pos file_pos64; - int err = unzGetFilePos64(file,&file_pos64); - if (err==UNZ_OK) - { - file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; - file_pos->num_of_file = (uLong)file_pos64.num_of_file; - } - return err; -} - -extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) -{ - unz64_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos) -{ - unz64_file_pos file_pos64; - if (file_pos == NULL) - return UNZ_PARAMERROR; - - file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; - file_pos64.num_of_file = file_pos->num_of_file; - return unzGoToFilePos64(file,&file_pos64); -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, - ZPOS64_T * poffset_local_extrafield, - uInt * psize_local_extrafield) -{ - uLong uMagic,uData,uFlags; + uLong uMagic,uL,uFlags; uLong size_filename; uLong size_extra_field; - int err=UNZ_OK; + int err = UNZ_OK; + int compression_method = 0; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; - if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = unzGoToNextDisk((unzFile)s); + if (err != UNZ_OK) + return err; + + if (ZSEEK64(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + + s->cur_file_info_internal.byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) return UNZ_ERRNO; - if (err==UNZ_OK) + if (err == UNZ_OK) { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic!=LOCALHEADERMAGIC) + err = UNZ_BADZIPFILE; } - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + err = UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uL!=s->cur_file_info.compression_method)) + err = UNZ_BADZIPFILE; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; + compression_method = (int)s->cur_file_info.compression_method; +#ifdef HAVE_AES + if (compression_method == AES_METHOD) + compression_method = (int)s->cur_file_info_internal.aes_compression_method; +#endif - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; + if ((err == UNZ_OK) && (compression_method != 0) && +#ifdef HAVE_BZIP2 + (compression_method != Z_BZIP2ED) && +#endif + (compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* date/time */ + err = UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* crc */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uL!=s->cur_file_info.crc) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* size compr */ + err = UNZ_ERRNO; + else if ((uL != 0xffffffff) && (err == UNZ_OK) && (uL!=s->cur_file_info.compressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* size uncompr */ + err = UNZ_ERRNO; + else if ((uL != 0xffffffff) && (err == UNZ_OK) && (uL!=s->cur_file_info.uncompressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err = UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK) + err = UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; @@ -1469,56 +1120,61 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, - int* level, int raw, const char* password) +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method, int* level, int raw, const char* password) { - int err=UNZ_OK; + int err = UNZ_OK; + int compression_method; uInt iSizeVar; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT +#ifndef NOUNCRYPT char source[12]; -# else +#else if (password != NULL) return UNZ_PARAMERROR; -# endif - - if (file==NULL) +#endif + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; + s = (unz64_s*)file; if (!s->current_file_ok) return UNZ_PARAMERROR; if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile(file); - if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) return UNZ_BADZIPFILE; pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); - if (pfile_in_zip_read_info==NULL) + if (pfile_in_zip_read_info == NULL) return UNZ_INTERNALERROR; - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->read_buffer = (Bytef*)ALLOC(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; - if (pfile_in_zip_read_info->read_buffer==NULL) + if (pfile_in_zip_read_info->read_buffer == NULL) { TRYFREE(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } - pfile_in_zip_read_info->stream_initialised=0; + pfile_in_zip_read_info->stream_initialised = 0; - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; + compression_method = (int)s->cur_file_info.compression_method; +#ifdef HAVE_AES + if (compression_method == AES_METHOD) + compression_method = (int)s->cur_file_info_internal.aes_compression_method; +#endif - if (level!=NULL) + if (method != NULL) + *method = compression_method; + + if (level != NULL) { *level = 6; switch (s->cur_file_info.flag & 0x06) @@ -1529,275 +1185,308 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, } } - if ((s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - - /* err=UNZ_BADZIPFILE */; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->total_out_64=0; - pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) - { + if ((compression_method != 0) && #ifdef HAVE_BZIP2 - pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; - pfile_in_zip_read_info->bstream.bzfree = (free_func)0; - pfile_in_zip_read_info->bstream.opaque = (voidpf)0; - pfile_in_zip_read_info->bstream.state = (voidpf)0; - - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } -#else - pfile_in_zip_read_info->raw=1; + (compression_method != Z_BZIP2ED) && #endif - } - else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + (compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->total_out_64 = 0; + pfile_in_zip_read_info->compression_method = compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + if (s->number_disk == s->gi.number_disk_with_CD) + pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + else + pfile_in_zip_read_info->byte_before_the_zipfile = 0; + pfile_in_zip_read_info->stream.total_out = 0; + pfile_in_zip_read_info->stream.total_in = 0; + pfile_in_zip_read_info->stream.next_in = NULL; + + if (!raw) { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = 0; - pfile_in_zip_read_info->stream.avail_in = 0; + if (compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if (compression_method == Z_DEFLATED) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)s; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised = Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; + pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size; + pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; - s->encrypted = 0; + s->encrypted = 0; -# ifndef NOUNCRYPT +#ifndef NOUNCRYPT if (password != NULL) { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); if (ZSEEK64(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) return UNZ_INTERNALERROR; + s->encrypted = 1; +#ifdef HAVE_AES + if (s->cur_file_info.compression_method == AES_METHOD) + { + unsigned char passverify[AES_PWVERIFYSIZE]; + unsigned char saltvalue[AES_MAXSALTLENGTH]; + uInt saltlength; - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); + if ((s->cur_file_info_internal.aes_encryption_mode < 1) || + (s->cur_file_info_internal.aes_encryption_mode > 3)) + return UNZ_INTERNALERROR; - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; + saltlength = SALT_LENGTH(s->cur_file_info_internal.aes_encryption_mode); + + if (ZREAD64(s->z_filefunc, s->filestream, saltvalue, saltlength) != saltlength) + return UNZ_INTERNALERROR; + if (ZREAD64(s->z_filefunc, s->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE) + return UNZ_INTERNALERROR; + + fcrypt_init(s->cur_file_info_internal.aes_encryption_mode, password, strlen(password), saltvalue, + passverify, &s->pfile_in_zip_read->aes_ctx); + + pfile_in_zip_read_info->rest_read_compressed -= saltlength + AES_PWVERIFYSIZE; + pfile_in_zip_read_info->rest_read_compressed -= AES_AUTHCODESIZE; + + s->pfile_in_zip_read->pos_in_zipfile += saltlength + AES_PWVERIFYSIZE; + } + else +#endif + { + int i; + s->pcrc_32_tab = (const unsigned long*)get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + + if (ZREAD64(s->z_filefunc, s->filestream, source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys, s->pcrc_32_tab, source[i]); + + pfile_in_zip_read_info->rest_read_compressed -= 12; + + s->pfile_in_zip_read->pos_in_zipfile += 12; + } } -# endif - +#endif return UNZ_OK; } -extern int ZEXPORT unzOpenCurrentFile (unzFile file) +extern int ZEXPORT unzOpenCurrentFile(unzFile file) { return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } -extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) { return unzOpenCurrentFile3(file, NULL, NULL, 0, password); } -extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) { return unzOpenCurrentFile3(file, method, level, raw, NULL); } -/** Addition for GDAL : START */ +/* Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) + return the number of byte copied if some bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { + int err = UNZ_OK; + uInt read = 0; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; - s=(unz64_s*)file; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - pfile_in_zip_read_info=s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return 0; //UNZ_PARAMERROR; - return pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile; -} - -/** Addition for GDAL : END */ - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) -{ - int err=UNZ_OK; - uInt iRead = 0; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) + if (pfile_in_zip_read_info == NULL) return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; - if (len==0) + if (len == 0) return 0; pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; + if (pfile_in_zip_read_info->raw) + { + if (len > pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in) + pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed + + pfile_in_zip_read_info->stream.avail_in; + } + else + { + if (len > pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + } while (pfile_in_zip_read_info->stream.avail_out>0) { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) + if (pfile_in_zip_read_info->stream.avail_in == 0) { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) + uInt bytes_to_read = UNZ_BUFSIZE; + uInt bytes_not_read = 0; + uInt bytes_read = 0; + uInt total_bytes_read = 0; + + if (pfile_in_zip_read_info->stream.next_in != NULL) + bytes_not_read = pfile_in_zip_read_info->read_buffer + UNZ_BUFSIZE - + pfile_in_zip_read_info->stream.next_in; + bytes_to_read -= bytes_not_read; + if (bytes_not_read > 0) + memcpy(pfile_in_zip_read_info->read_buffer, pfile_in_zip_read_info->stream.next_in, bytes_not_read); + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (bytes_to_read == 0) return UNZ_EOF; - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - -# ifndef NOUNCRYPT - if(s->encrypted) + while (total_bytes_read != bytes_to_read) { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + bytes_read = ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer + bytes_not_read + total_bytes_read, + bytes_to_read - total_bytes_read); + + total_bytes_read += bytes_read; + pfile_in_zip_read_info->pos_in_zipfile += bytes_read; + + if (bytes_read == 0) + { + if (ZERROR64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream)) + return UNZ_ERRNO; + + err = unzGoToNextDisk(file); + if (err != UNZ_OK) + return err; + + pfile_in_zip_read_info->pos_in_zipfile = 0; + pfile_in_zip_read_info->filestream = s->filestream; + } } -# endif +#ifndef NOUNCRYPT + if (s->encrypted) + { +#ifdef HAVE_AES + if (s->cur_file_info.compression_method == AES_METHOD) + { + fcrypt_decrypt(pfile_in_zip_read_info->read_buffer, bytes_to_read, &s->pfile_in_zip_read->aes_ctx); + } + else +#endif + { + uInt i; + for(i = 0; i < total_bytes_read; i++) + pfile_in_zip_read_info->read_buffer[i] = + zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]); + } + } +#endif - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + pfile_in_zip_read_info->rest_read_compressed -= total_bytes_read; + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)bytes_not_read + total_bytes_read; } - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) { - uInt uDoCopy,i ; + uInt copy,i; if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; + return (read == 0) ? UNZ_EOF : read; - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) + copy = pfile_in_zip_read_info->stream.avail_out; else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + copy = pfile_in_zip_read_info->stream.avail_in; - for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; - + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + copy; + pfile_in_zip_read_info->rest_read_uncompressed -= copy; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; + pfile_in_zip_read_info->stream.next_out, copy); + + pfile_in_zip_read_info->stream.avail_in -= copy; + pfile_in_zip_read_info->stream.avail_out -= copy; + pfile_in_zip_read_info->stream.next_out += copy; + pfile_in_zip_read_info->stream.next_in += copy; + pfile_in_zip_read_info->stream.total_out += copy; + read += copy; } - else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + else if (pfile_in_zip_read_info->compression_method == Z_BZIP2ED) { #ifdef HAVE_BZIP2 - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; + uLong total_out_before, total_out_after; + const Bytef *buf_before; + uLong out_bytes; pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; @@ -1808,19 +1497,19 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; pfile_in_zip_read_info->bstream.total_out_hi32 = 0; - uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; - bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + total_out_before = pfile_in_zip_read_info->bstream.total_out_lo32; + buf_before = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; - err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + err = BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); - uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; - uOutThis = uTotalOutAfter-uTotalOutBefore; + total_out_after = pfile_in_zip_read_info->bstream.total_out_lo32; + out_bytes = total_out_after-total_out_before; - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + out_bytes; + pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes; + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,buf_before, (uInt)(out_bytes)); - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); - pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + read += (uInt)(total_out_after - total_out_before); pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; @@ -1829,21 +1518,21 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; - if (err==BZ_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=BZ_OK) - break; + if (err == BZ_STREAM_END) + return (read == 0) ? UNZ_EOF : read; + if (err != BZ_OK) + break; #endif - } // end Z_BZIP2ED + } else { - ZPOS64_T uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - ZPOS64_T uOutThis; + ZPOS64_T total_out_before, total_out_after; + const Bytef *buf_before; + ZPOS64_T out_bytes; int flush=Z_SYNC_FLUSH; - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; + total_out_before = pfile_in_zip_read_info->stream.total_out; + buf_before = pfile_in_zip_read_info->stream.next_out; /* if ((pfile_in_zip_read_info->rest_read_uncompressed == @@ -1851,176 +1540,124 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) (pfile_in_zip_read_info->rest_read_compressed == 0)) flush = Z_FINISH; */ - err=inflate(&pfile_in_zip_read_info->stream,flush); + err = inflate(&pfile_in_zip_read_info->stream,flush); - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != NULL)) err = Z_DATA_ERROR; - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + total_out_after = pfile_in_zip_read_info->stream.total_out; + out_bytes = total_out_after-total_out_before; + pfile_in_zip_read_info->total_out_64 += out_bytes; + pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes; pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); + crc32(pfile_in_zip_read_info->crc32,buf_before, (uInt)(out_bytes)); - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; + read += (uInt)(total_out_after - total_out_before); - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) + if (err == Z_STREAM_END) + return (read == 0) ? UNZ_EOF : read; + if (err != Z_OK) break; } } - if (err==Z_OK) - return iRead; + if (err == Z_OK) + return read; return err; } - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (unzFile file) +/* Addition for GDAL : START */ +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; + s = (unz64_s*)file; + if (file == NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info= s->pfile_in_zip_read; + if (pfile_in_zip_read_info == NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile; } +/* Addition for GDAL : END */ -extern ZPOS64_T ZEXPORT unztell64 (unzFile file) -{ - - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return (ZPOS64_T)-1; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return (ZPOS64_T)-1; - - return pfile_in_zip_read_info->total_out_64; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (unzFile file) -{ - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* -Read extra field from the current file (opened by unzOpenCurrentFile) -This is the local-header version of the extra field (sometimes, there is -more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; uInt read_now; ZPOS64_T size_to_read; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) + if (pfile_in_zip_read_info == NULL) return UNZ_PARAMERROR; - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); + size_to_read = pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield; - if (buf==NULL) + if (buf == NULL) return (int)size_to_read; - if (len>size_to_read) + if (len > size_to_read) read_now = (uInt)size_to_read; else read_now = (uInt)len ; - if (read_now==0) + if (read_now == 0) return 0; - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET) != 0) return UNZ_ERRNO; - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf, read_now) != read_now) return UNZ_ERRNO; return (int)read_now; } -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (unzFile file) +extern int ZEXPORT unzCloseCurrentFile(unzFile file) { - int err=UNZ_OK; + int err = UNZ_OK; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; + s = (unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) + if (pfile_in_zip_read_info == NULL) return UNZ_PARAMERROR; - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) +#ifdef HAVE_AES + if (s->cur_file_info.compression_method == AES_METHOD) { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; + unsigned char authcode[AES_AUTHCODESIZE]; + unsigned char rauthcode[AES_AUTHCODESIZE]; + + if (ZREAD64(s->z_filefunc, s->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE) + return UNZ_ERRNO; + + if (fcrypt_end(rauthcode, &s->pfile_in_zip_read->aes_ctx) != AES_AUTHCODESIZE) + err = UNZ_CRCERROR; + if (memcmp(authcode, rauthcode, AES_AUTHCODESIZE) != 0) + err = UNZ_CRCERROR; + } + else +#endif + { + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err = UNZ_CRCERROR; + } } @@ -2033,72 +1670,202 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); #endif - pfile_in_zip_read_info->stream_initialised = 0; TRYFREE(pfile_in_zip_read_info); - s->pfile_in_zip_read=NULL; + s->pfile_in_zip_read = NULL; return err; } + +extern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size) +{ + int err = UNZ_OK; + unz64_s* s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, + filename,filename_size, extrafield,extrafield_size, comment,comment_size); + s->current_file_ok = (err == UNZ_OK); + if ((err == UNZ_OK) && (pfile_info != NULL)) + memcpy(pfile_info, &s->cur_file_info, sizeof(unz_file_info64)); + return err; +} + +extern int ZEXPORT unzGoToFirstFile(unzFile file) +{ + return unzGoToFirstFile2(file, NULL, NULL, 0, NULL, 0, NULL, 0); +} - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +extern int ZEXPORT unzGoToNextFile2(unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size) { unz64_s* s; - uLong uReadThis ; - if (file==NULL) - return (int)UNZ_PARAMERROR; - s=(unz64_s*)file; + int err; - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1 == s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, + filename, filename_size, extrafield,extrafield_size, comment,comment_size); + s->current_file_ok = (err == UNZ_OK); + if ((err == UNZ_OK) && (pfile_info != NULL)) + memcpy(pfile_info, &s->cur_file_info, sizeof(unz_file_info64)); + return err; +} - if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; +extern int ZEXPORT unzGoToNextFile(unzFile file) +{ + return unzGoToNextFile2(file, NULL, NULL, 0, NULL, 0, NULL, 0); +} - if (uReadThis>0) +extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func) +{ + unz64_s* s; + int err; + unz_file_info64 cur_file_info_saved; + unz_file_info64_internal cur_file_info_internal_saved; + ZPOS64_T num_file_saved; + ZPOS64_T pos_in_central_dir_saved; + char current_filename[UNZ_MAXFILENAMEINZIP+1]; + + + if (file == NULL) + return UNZ_PARAMERROR; + if (strlen(filename) >= UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_file_saved = s->num_file; + pos_in_central_dir_saved = s->pos_in_central_dir; + cur_file_info_saved = s->cur_file_info; + cur_file_info_internal_saved = s->cur_file_info_internal; + + err = unzGoToFirstFile2(file, NULL, current_filename, sizeof(current_filename)-1, NULL, 0, NULL, 0); + + while (err == UNZ_OK) { - *szComment='\0'; - if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; + if (filename_compare_func != NULL) + err = filename_compare_func(file, current_filename, filename); + else + err = strcmp(current_filename, filename); + if (err == 0) + return UNZ_OK; + err = unzGoToNextFile2(file, NULL, current_filename, sizeof(current_filename)-1, NULL, 0, NULL, 0); } - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; + /* We failed, so restore the state of the 'current file' to where we were. */ + s->num_file = num_file_saved; + s->pos_in_central_dir = pos_in_central_dir_saved; + s->cur_file_info = cur_file_info_saved; + s->cur_file_info_internal = cur_file_info_internal_saved; + return err; +} + +/* Additions by Ryan Haksi (mailto://cryogen@infoserve.net) for random access */ +extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err == UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + + if (file_pos == NULL) + return UNZ_PARAMERROR; + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal,NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; } /* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset(unzFile file) +{ + ZPOS64_T offset64; + + if (file == NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { unz64_s* s; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - s=(unz64_s*)file; + if (file == NULL) + return 0; //UNZ_PARAMERROR; + s = (unz64_s*)file; if (!s->current_file_ok) - return 0; + return 0; if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; + if (s->num_file == s->gi.number_entry) + return 0; return s->pos_in_central_dir; } -extern uLong ZEXPORT unzGetOffset (unzFile file) +extern int ZEXPORT unzSetOffset(unzFile file, uLong pos) { - ZPOS64_T offset64; - - if (file==NULL) - return 0; //UNZ_PARAMERROR; - offset64 = unzGetOffset64(file); - return (uLong)offset64; + return unzSetOffset64(file, pos); } extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) @@ -2106,20 +1873,59 @@ extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) unz64_s* s; int err; - if (file==NULL) + if (file == NULL) return UNZ_PARAMERROR; - s=(unz64_s*)file; + s = (unz64_s*)file; s->pos_in_central_dir = pos; s->num_file = s->gi.number_entry; /* hack */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); s->current_file_ok = (err == UNZ_OK); return err; } -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +extern z_off_t ZEXPORT unztell(unzFile file) { - return unzSetOffset64(file,pos); + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + return (z_off_t)pfile_in_zip_read_info->stream.total_out; } + +extern ZPOS64_T ZEXPORT unztell64(unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return (ZPOS64_T)-1; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + +extern int ZEXPORT unzeof(unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + return 0; +} \ No newline at end of file diff --git a/MiniZip/unzip.h b/MiniZip/unzip.h old mode 100644 new mode 100755 index 3183968..10192be --- a/MiniZip/unzip.h +++ b/MiniZip/unzip.h @@ -2,42 +2,37 @@ Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications of Unzip for Zip64 - Copyright (C) 2007-2008 Even Rouault + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault - Modifications for Zip64 support on both zip and unzip - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read MiniZip_info.txt - --------------------------------------------------------------------------------- + --------------------------------------------------------------------------------- - Condition of use and distribution are the same than zlib : + Condition of use and distribution are the same than zlib : - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - --------------------------------------------------------------------------------- - - Changes - - See header of unzip64.c + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + --------------------------------------------------------------------------------- */ #ifndef _unz64_H @@ -83,27 +78,27 @@ typedef voidp unzFile; /* tm_unz contain date/time info */ typedef struct tm_unz_s { - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ } tm_unz; /* unz_global_info structure contain global data about the ZIPfile These data comes from the end of central dir */ typedef struct unz_global_info64_s { - ZPOS64_T number_entry; /* total number of entries in - the central dir on this disk */ + ZPOS64_T number_entry; /* total number of entries in the central dir on this disk */ + uLong number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/ uLong size_comment; /* size of the global comment of the zipfile */ } unz_global_info64; typedef struct unz_global_info_s { - uLong number_entry; /* total number of entries in - the central dir on this disk */ + uLong number_entry; /* total number of entries in the central dir on this disk */ + uLong number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/ uLong size_comment; /* size of the global comment of the zipfile */ } unz_global_info; @@ -127,6 +122,8 @@ typedef struct unz_file_info64_s uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; + ZPOS64_T disk_offset; + uLong size_file_extra_internal; } unz_file_info64; typedef struct unz_file_info_s @@ -148,126 +145,164 @@ typedef struct unz_file_info_s uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; + uLong disk_offset; } unz_file_info; -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - +/***************************************************************************/ +/* Opening and close a zip file */ extern unzFile ZEXPORT unzOpen OF((const char *path)); extern unzFile ZEXPORT unzOpen64 OF((const void *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. - the "64" function take a const void* pointer, because the path is just the - value passed to the open64_file_func callback. - Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path - is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* - does not describe the reality -*/ +/* Open a Zip file. + path should contain the full pathname (by example, on a Windows XP computer + "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip". + return NULL if zipfile cannot be opened or doesn't exist + return unzFile handle if no error -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ + NOTE: The "64" function take a const void* pointer, because the path is just the value passed to the + open64_file_func callback. Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* does not describe the reality */ -extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, - zlib_filefunc64_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unz64Open, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ +extern unzFile ZEXPORT unzOpen2 OF((const char *path, zlib_filefunc_def* pzlib_filefunc_def)); +/* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write operations */ +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, zlib_filefunc64_def* pzlib_filefunc_def)); +/* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write 64-bit operations */ extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ +/* Close a ZipFile opened with unzipOpen. If there is files inside the .Zip opened with unzOpenCurrentFile, + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); + return UNZ_OK if there is no error */ -extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, - unz_global_info64 *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, unz_global_info *pglobal_info)); +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, unz_global_info64 *pglobal_info)); +/* Write info about the ZipFile in the *pglobal_info structure. + return UNZ_OK if no error */ -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *comment, uLong comment_size)); +/* Get the global comment string of the ZipFile, in the comment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 */ /***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ +/* Reading the content of the current zipfile, you can open it, read data from it, and close it + (you can close it before reading all the file) */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* Open for reading data the current file in the zipfile. + + return UNZ_OK if no error */ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, const char* password)); +/* Open for reading data the current file in the zipfile. + password is a crypting password + + return UNZ_OK if no error */ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, int* method, int* level, int raw)); +/* Same as unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 *method will receive method of compression, *level will receive level of compression + + NOTE: you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL */ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, int* method, int* level, int raw, const char* password)); +/* Same as unzOpenCurrentFile, but takes extra parameter password for encrypted files */ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len)); +/* Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)); +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)); +/* Get Info about the current file + + pfile_info if != NULL, the *pfile_info structure will contain somes info about the current file + filename if != NULL, the file name string will be copied in filename + filename_size is the size of the filename buffer + extrafield if != NULL, the extra field information from the central header will be copied in to + extrafield_size is the size of the extraField buffer + comment if != NULL, the comment string of the file will be copied in to + comment_size is the size of the comment buffer */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, voidp buf, unsigned len)); +/* Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf == NULL, it return the size of the local extra field + if buf != NULL, len is the size of the buffer, the extra header is copied in buf. + + return number of bytes copied in buf, or (if <0) the error code */ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* Close the file in zip opened with unzOpenCurrentFile + + return UNZ_CRCERROR if all the file was read but the CRC is not good */ + +/***************************************************************************/ +/* Browse the directory of the zipfile */ + +typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2); +typedef int (*unzIteratorFunction)(unzFile file); +typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size); extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ +/* Set the current file of the zipfile to the first file. + + return UNZ_OK if no error */ + +extern int ZEXPORT unzGoToFirstFile2 OF((unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)); +/* Set the current file of the zipfile to the first file and retrieves the current info on success. + Not as seek intensive as unzGoToFirstFile + unzGetCurrentFileInfo. + + return UNZ_OK if no error */ extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ +/* Set the current file of the zipfile to the next file. -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare + return UNZ_OK if no error + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */ - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ +extern int ZEXPORT unzGoToNextFile2 OF((unzFile file, unz_file_info64 *pfile_info, char *filename, + uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)); +/* Set the current file of the zipfile to the next file and retrieves the current + info on success. Does less seeking around than unzGotoNextFile + unzGetCurrentFileInfo. + return UNZ_OK if no error + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */ + +extern int ZEXPORT unzLocateFile OF((unzFile file, const char *filename, unzFileNameComparer filename_compare_func)); +/* Try locate the file szFileName in the zipfile. For custom filename comparison pass in comparison function. + + return UNZ_OK if the file is found (it becomes the current file) + return UNZ_END_OF_LIST_OF_FILE if the file is not found */ + +/***************************************************************************/ +/* Raw access to zip file */ -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_pos_s { - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ } unz_file_pos; -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); +extern int ZEXPORT unzGetFilePos OF((unzFile file, unz_file_pos* file_pos)); +extern int ZEXPORT unzGoToFilePos OF((unzFile file, unz_file_pos* file_pos)); typedef struct unz64_file_pos_s { @@ -275,161 +310,26 @@ typedef struct unz64_file_pos_s ZPOS64_T num_of_file; /* # of file */ } unz64_file_pos; -extern int ZEXPORT unzGetFilePos64( - unzFile file, - unz64_file_pos* file_pos); +extern int ZEXPORT unzGetFilePos64 OF((unzFile file, unz64_file_pos* file_pos)); +extern int ZEXPORT unzGoToFilePos64 OF((unzFile file, const unz64_file_pos* file_pos)); -extern int ZEXPORT unzGoToFilePos64( - unzFile file, - const unz64_file_pos* file_pos); +extern uLong ZEXPORT unzGetOffset OF((unzFile file)); +extern ZPOS64_T ZEXPORT unzGetOffset64 OF((unzFile file)); +/* Get the current file offset */ -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, - unz_file_info64 *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - - -/** Addition for GDAL : START */ - -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); - -/** Addition for GDAL : END */ - - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ +extern int ZEXPORT unzSetOffset OF((unzFile file, uLong pos)); +extern int ZEXPORT unzSetOffset64 OF((unzFile file, ZPOS64_T pos)); +/* Set the current file offset */ extern z_off_t ZEXPORT unztell OF((unzFile file)); - extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ +/* return current position in uncompressed data */ extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ +/* return 1 if the end of file was reached, 0 elsewhere */ /***************************************************************************/ -/* Get the current file offset */ -extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - #ifdef __cplusplus } #endif diff --git a/MiniZip/zip.c b/MiniZip/zip.c old mode 100644 new mode 100755 index 296d08e..568e5e6 --- a/MiniZip/zip.c +++ b/MiniZip/zip.c @@ -2,26 +2,33 @@ Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read MiniZip_info.txt + + ------------------------------------------------------------------------------------ + + Changes in zip.c - Changes Oct-2009 - Mathias Svensson - Remove old C style function prototypes Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data It is used when recreting zip archive with RAW when deleting items from a zip. - ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 + data need to be removed. Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + Aug-2010 - Nathan Moinvaziri - Added PKZIP spanning support + May-2012 - Nathan Moinvaziri - Added AES encryption support + Jul-2012 - Nathan Moinvaziri - Clean up, removed zipRemoveExtraInfoBlock + ------------------------------------------------------------------------------------ */ - #include #include #include @@ -40,20 +47,57 @@ # include #endif +#ifdef HAVE_AES +#define AES_METHOD (99) +#define AES_PWVERIFYSIZE (2) +#define AES_AUTHCODESIZE (10) +#define AES_MAXSALTLENGTH (16) +#define AES_VERSION (0x0001) +#define AES_ENCRYPTIONMODE (0x03) + +#include "aes/aes.h" +#include "aes/fileenc.h" +#include "aes/prng.h" +#include "aes/entropy.h" +#endif + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define DISKHEADERMAGIC (0x08074b50) +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x06064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x07064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ +#define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */ +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif #ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ +#define VERSIONMADEBY (0x0) /* platform dependent */ #endif #ifndef Z_BUFSIZE -#define Z_BUFSIZE (64*1024) //(16384) +#define Z_BUFSIZE (64*1024) #endif - #ifndef Z_MAXFILENAMEINZIP #define Z_MAXFILENAMEINZIP (256) #endif @@ -65,29 +109,9 @@ # define TRYFREE(p) {if (p) free(p);} #endif -/* -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) -*/ - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - - // NOT sure that this work on ALL platform #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - #ifndef DEF_MEM_LEVEL #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 @@ -95,29 +119,16 @@ # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif + const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -#define SIZEDATA_INDATABLOCK (4096-(4*4)) - -#define LOCALHEADERMAGIC (0x04034b50) -#define CENTRALHEADERMAGIC (0x02014b50) -#define ENDHEADERMAGIC (0x06054b50) -#define ZIP64ENDHEADERMAGIC (0x6064b50) -#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) - -#define FLAG_LOCALHEADER_OFFSET (0x06) -#define CRC_LOCALHEADER_OFFSET (0x0e) - -#define SIZECENTRALHEADER (0x2e) /* 46 */ - typedef struct linkedlist_datablock_internal_s { - struct linkedlist_datablock_internal_s* next_datablock; - uLong avail_in_this_block; - uLong filled_in_this_block; - uLong unused; /* for future use and alignement */ - unsigned char data[SIZEDATA_INDATABLOCK]; + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignment */ + unsigned char data[SIZEDATA_INDATABLOCK]; } linkedlist_datablock_internal; typedef struct linkedlist_data_s @@ -126,37 +137,40 @@ typedef struct linkedlist_data_s linkedlist_datablock_internal* last_block; } linkedlist_data; - typedef struct { - z_stream stream; /* zLib stream structure for inflate */ + z_stream stream; /* zLib stream structure for inflate */ #ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ + bz_stream bstream; /* bzLib stream structure for bziped */ #endif +#ifdef HAVE_AES + fcrypt_ctx aes_ctx; + prng_ctx aes_rng[1]; +#endif + int stream_initialised; /* 1 is stream is initialized */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ - int stream_initialised; /* 1 is stream is initialised */ - uInt pos_in_buffered_data; /* last written byte in buffered_data */ - - ZPOS64_T pos_local_header; /* offset of the local header of the file - currenty writing */ - char* central_header; /* central header data for the current file */ + ZPOS64_T pos_local_header; /* offset of the local header of the file currently writing */ + char* central_header; /* central header data for the current file */ uLong size_centralExtra; - uLong size_centralheader; /* size of the central header for cur file */ - uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ - uLong flag; /* flag of the file currently writing */ + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the central header but that are not used */ + uLong flag; /* flag of the file currently writing */ - int method; /* compression method of file currenty wr.*/ - int raw; /* 1 for directly writing raw data */ - Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + int method; /* compression method written to file.*/ + int compression_method; /* compression method to use */ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; int encrypt; - int zip64; /* Add ZIP64 extened information in the extra field */ + int zip64; /* Add ZIP64 extended information in the extra field */ + uLong number_disk; /* number of current disk used for spanning ZIP */ ZPOS64_T pos_zip64extrainfo; ZPOS64_T totalCompressedData; ZPOS64_T totalUncompressedData; #ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const unsigned long* pcrc_32_tab; int crypt_header_size; #endif @@ -165,44 +179,46 @@ typedef struct typedef struct { zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - linkedlist_data central_dir;/* datablock with central dir in construction*/ - int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile64_info ci; /* info on the file curretly writing */ + voidpf filestream; /* io structure of the zipfile */ + voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */ + linkedlist_data central_dir; /* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + int append; /* append mode */ + curfile64_info ci; /* info on the file currently writing */ - ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ ZPOS64_T add_position_when_writting_offset; ZPOS64_T number_entry; - + ZPOS64_T disk_size; /* size of each disk */ + uLong number_disk; /* number of the current disk, used for spanning ZIP */ + uLong number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */ #ifndef NO_ADDFILEINEXISTINGZIP char *globalcomment; #endif - } zip64_internal; - -#ifndef NOCRYPT -#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#include "crypt.h" -#endif - +/* Allocate a new data block */ +local linkedlist_datablock_internal* allocate_new_datablock OF(()); local linkedlist_datablock_internal* allocate_new_datablock() { linkedlist_datablock_internal* ldi; - ldi = (linkedlist_datablock_internal*) - ALLOC(sizeof(linkedlist_datablock_internal)); - if (ldi!=NULL) + + ldi = (linkedlist_datablock_internal*)ALLOC(sizeof(linkedlist_datablock_internal)); + + if (ldi != NULL) { - ldi->next_datablock = NULL ; - ldi->filled_in_this_block = 0 ; - ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + ldi->next_datablock = NULL; + ldi->filled_in_this_block = 0; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK; } return ldi; } +/* Free data block in linked list */ +local void free_datablock OF((linkedlist_datablock_internal* ldi)); local void free_datablock(linkedlist_datablock_internal* ldi) { - while (ldi!=NULL) + while (ldi != NULL) { linkedlist_datablock_internal* ldinext = ldi->next_datablock; TRYFREE(ldi); @@ -210,24 +226,29 @@ local void free_datablock(linkedlist_datablock_internal* ldi) } } +/* Initialize linked list */ +local void init_linkedlist OF((linkedlist_data* ll)); local void init_linkedlist(linkedlist_data* ll) { ll->first_block = ll->last_block = NULL; } +/* Free entire linked list and all data blocks */ +local void free_linkedlist OF((linkedlist_data* ll)); local void free_linkedlist(linkedlist_data* ll) { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } - +/* Add data to linked list data block */ +local int add_data_in_datablock OF((linkedlist_data* ll, const void* buf, uLong len)); local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { linkedlist_datablock_internal* ldi; const unsigned char* from_copy; - if (ll==NULL) + if (ll == NULL) return ZIP_INTERNALERROR; if (ll->last_block == NULL) @@ -246,7 +267,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) uInt i; unsigned char* to_copy; - if (ldi->avail_in_this_block==0) + if (ldi->avail_in_this_block == 0) { ldi->next_datablock = allocate_new_datablock(); if (ldi->next_datablock == NULL) @@ -273,18 +294,24 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) return ZIP_OK; } +local uLong zip64local_TmzDateToDosDate OF((const tm_zip* ptm)); +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year >= 1980) + year -= 1980; + else if (year >= 80) + year -= 80; + return + (uLong)(((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} - -/****************************************************************************/ - -#ifndef NO_ADDFILEINEXISTINGZIP -/* =========================================================================== - Inputs a long in LSB order to the given file - nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) -*/ - -local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); -local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +/* Inputs a long in LSB order to the given file: nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */ +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + ZPOS64_T x, int nbByte) { unsigned char buf[8]; int n; @@ -294,23 +321,24 @@ local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, x >>= 8; } if (x != 0) - { /* data overflow - hack for ZIP64 (X Roche) */ - for (n = 0; n < nbByte; n++) + { + /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) { - buf[n] = 0xff; + buf[n] = 0xff; } - } + } if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) return ZIP_ERRNO; - else - return ZIP_OK; + + return ZIP_OK; } local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { - unsigned char* buf=(unsigned char*)dest; + unsigned char* buf =(unsigned char*)dest; int n; for (n = 0; n < nbByte; n++) { buf[n] = (unsigned char)(x & 0xff); @@ -318,7 +346,8 @@ local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) } if (x != 0) - { /* data overflow - hack for ZIP64 */ + { + /* data overflow - hack for ZIP64 */ for (n = 0; n < nbByte; n++) { buf[n] = 0xff; @@ -326,64 +355,35 @@ local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) } } -/****************************************************************************/ - - -local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) -{ - uLong year = (uLong)ptm->tm_year; - if (year>=1980) - year-=1980; - else if (year>=80) - year-=80; - return - (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | - ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); -} - - -/****************************************************************************/ - local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); - local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) { unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) + int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c,1); + if (err == 1) { *pi = (int)c; return ZIP_OK; } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return ZIP_ERRNO; - else - return ZIP_EOF; - } + if (ZERROR64(*pzlib_filefunc_def, filestream)) + return ZIP_ERRNO; + return ZIP_EOF; } - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { - uLong x ; + uLong x; int i = 0; int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); x = (uLong)i; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 8; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==ZIP_OK) + if (err == ZIP_OK) *pX = x; else *pX = 0; @@ -391,29 +391,25 @@ local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, } local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { - uLong x ; + uLong x; int i = 0; int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); x = (uLong)i; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); x += ((uLong)i)<<8; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); x += ((uLong)i)<<16; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); x += ((uLong)i)<<24; - if (err==ZIP_OK) + if (err == ZIP_OK) *pX = x; else *pX = 0; @@ -421,456 +417,293 @@ local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, } local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); - - local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { - ZPOS64_T x; - int i = 0; - int err; + ZPOS64_T x; + int i = 0; + int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (ZPOS64_T)i; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<8; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<16; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<24; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<32; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<40; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<48; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i)<<56; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<8; + if (err == ZIP_OK) + *pX = x; + else + *pX = 0; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<16; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<24; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<32; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<40; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<48; - - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<56; - - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - - return err; + return err; } -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +/* Gets the amount of bytes left to write to the current disk for spanning archives */ +local int zipGetDiskSizeAvailable OF((zipFile file, ZPOS64_T *size_available)); +local int zipGetDiskSizeAvailable(zipFile file, ZPOS64_T *size_available) +{ + zip64_internal* zi; + ZPOS64_T current_disk_size; + + zi = (zip64_internal*)file; + ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END); + current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream); + *size_available = zi->disk_size - current_disk_size; + return ZIP_OK; +} + +/* Goes to a specific disk number for spanning archives */ +local int zipGoToSpecificDisk OF((zipFile file, int number_disk, int open_existing)); +local int zipGoToSpecificDisk(zipFile file, int number_disk, int open_existing) +{ + zip64_internal* zi; + int err = ZIP_OK; + + + zi = (zip64_internal*)file; + if (zi->disk_size == 0) + return err; + + if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD)) + ZCLOSE64(zi->z_filefunc, zi->filestream); + + zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE)); + + if (zi->filestream == NULL) + err = ZIP_ERRNO; + + return err; +} + +/* Goes to the first disk in a spanned archive */ +local int zipGoToFirstDisk OF((zipFile file)); +local int zipGoToFirstDisk(zipFile file) +{ + zip64_internal* zi; + int number_disk_next; + int err = ZIP_OK; + + + zi = (zip64_internal*)file; + + if (zi->disk_size == 0) + return err; + number_disk_next = 0; + if (zi->number_disk_with_CD > 0) + number_disk_next = zi->number_disk_with_CD - 1; + err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP)); + if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP)) + err = zipGoToSpecificDisk(file, number_disk_next, 0); + if (err == ZIP_OK) + zi->number_disk = number_disk_next; + ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END); + return err; +} + +/* Goes to the next disk in a spanned archive */ +local int zipGoToNextDisk OF((zipFile file)); +local int zipGoToNextDisk(zipFile file) +{ + zip64_internal* zi; + ZPOS64_T size_available_in_disk; + int err = ZIP_OK; + int number_disk_next; + + + zi = (zip64_internal*)file; + + if (zi->disk_size == 0) + return err; + + number_disk_next = zi->number_disk + 1; + + do + { + err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP)); + if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP)) + err = zipGoToSpecificDisk(file, number_disk_next, 0); + if (err != ZIP_OK) + break; + err = zipGetDiskSizeAvailable(file, &size_available_in_disk); + if (err != ZIP_OK) + break; + zi->number_disk = number_disk_next; + zi->number_disk_with_CD = zi->number_disk + 1; + + number_disk_next += 1; + } + while (size_available_in_disk <= 0); + + return err; +} + +/* Locate the Central directory of a zipfile (at the end, just before the global comment) */ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf == NULL) + return 0; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; + if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + file_size = ZTELL64(*pzlib_filefunc_def, filestream); + + if (max_back > file_size) + max_back = file_size; + + while (back_read < max_back) + { + if (back_read + BUFREADCOMMENT > max_back) + back_read = max_back; + else + back_read += BUFREADCOMMENT; - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } + read_pos = file_size-back_read; + read_size = ((BUFREADCOMMENT+4) < (file_size-read_pos)) ? + (BUFREADCOMMENT+4) : (uLong)(file_size-read_pos); - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; + if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size) + break; + + for (i = (int)read_size-3; (i--) > 0;) + if ((*(buf+i)) == (ENDHEADERMAGIC & 0xff) && + (*(buf+i+1)) == (ENDHEADERMAGIC >> 8 & 0xff) && + (*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff) && + (*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff)) + { + pos_found = read_pos+i; + break; + } + + if (pos_found != 0) + break; + } + TRYFREE(buf); + return pos_found; } -/* -Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before -the global comment) -*/ -local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + const ZPOS64_T endcentraloffset)); +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, + const ZPOS64_T endcentraloffset) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - uLong uL; - ZPOS64_T relativeOffset; + ZPOS64_T offset; + uLong uL; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; + /* read locator signature */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + if (uL != ZIP64ENDLOCHEADERMAGIC) + return 0; + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK) + return 0; + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + if (uL != ZIP64ENDHEADERMAGIC) + return 0; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - { - // Signature "0x07064b50" Zip64 end of central directory locater - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } - } - - if (uPosFound!=0) - break; - } - - TRYFREE(buf); - if (uPosFound == 0) - return 0; - - /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature, already checked */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - - /* number of the disk with the start of the zip64 end of central directory */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 0) - return 0; - - /* relative offset of the zip64 end of central directory record */ - if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) - return 0; - - /* total number of disks */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 1) - return 0; - - /* Goto Zip64 end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; - - /* the signature */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - - if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' - return 0; - - return relativeOffset; + return offset; } -int LoadCentralDirectoryRecord(zip64_internal* pziinit) -{ - int err=ZIP_OK; - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory */ - ZPOS64_T central_pos; - uLong uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry; - ZPOS64_T number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - uLong VersionMadeBy; - uLong VersionNeeded; - uLong size_comment; - - int hasZIP64Record = 0; - - // check first if we find a ZIP64 record - central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); - if(central_pos > 0) - { - hasZIP64Record = 1; - } - else if(central_pos == 0) - { - central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); - } - -/* disable to allow appending to empty ZIP archive - if (central_pos==0) - err=ZIP_ERRNO; -*/ - - if(hasZIP64Record) - { - ZPOS64_T sizeEndOfCentralDirectory; - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; - - /* size of zip64 end of central directory record */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) - err=ZIP_ERRNO; - - /* version made by */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) - err=ZIP_ERRNO; - - /* version needed to extract */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of this disk */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of the disk with the start of the central directory */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central directory on this disk */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; - - /* size of the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; - - // TODO.. - // read the comment from the standard central header. - size_comment = 0; - } - else - { - // Read End of central Directory info - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=ZIP_ERRNO; - - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of this disk */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; - - /* number of the disk with the start of the central directory */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; - - /* total number of entries in the central dir on this disk */ - number_entry = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry = uL; - - /* total number of entries in the central dir */ - number_entry_CD = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry_CD = uL; - - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; - - /* size of the central directory */ - size_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - size_central_dir = uL; - - /* offset of start of central directory with respect to the starting disk number */ - offset_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - offset_central_dir = uL; - - - /* zipfile global comment length */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) - err=ZIP_ERRNO; - } - - if ((central_posz_filefunc, pziinit->filestream); - return ZIP_ERRNO; - } - - if (size_comment>0) - { - pziinit->globalcomment = (char*)ALLOC(size_comment+1); - if (pziinit->globalcomment) - { - size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); - pziinit->globalcomment[size_comment]=0; - } - } - - byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); - pziinit->add_position_when_writting_offset = byte_before_the_zipfile; - - { - ZPOS64_T size_central_dir_to_read = size_central_dir; - size_t buf_size = SIZEDATA_INDATABLOCK; - void* buf_read = (void*)ALLOC(buf_size); - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - while ((size_central_dir_to_read>0) && (err==ZIP_OK)) - { - ZPOS64_T read_this = SIZEDATA_INDATABLOCK; - if (read_this > size_central_dir_to_read) - read_this = size_central_dir_to_read; - - if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) - err=ZIP_ERRNO; - - if (err==ZIP_OK) - err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); - - size_central_dir_to_read-=read_this; - } - TRYFREE(buf_read); - } - pziinit->begin_pos = byte_before_the_zipfile; - pziinit->number_entry = number_entry_CD; - - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - return err; -} - - -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - - -/************************************************************/ -extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +extern zipFile ZEXPORT zipOpen4(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc* globalcomment, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { zip64_internal ziinit; zip64_internal* zi; - int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T number_entry_CD; /* total number of entries in the central dir */ + ZPOS64_T number_entry; + ZPOS64_T central_pos; + ZPOS64_T size_central_dir_to_read; + uLong uL; + uLong size_comment; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read; + int err = ZIP_OK; + int mode; ziinit.z_filefunc.zseek32_file = NULL; ziinit.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) + if (pzlib_filefunc64_32_def == NULL) fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); else ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + if (append == APPEND_STATUS_CREATE) + mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE); + else + mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING); - ziinit.filestream = ZOPEN64(ziinit.z_filefunc, - pathname, - (append == APPEND_STATUS_CREATE) ? - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); - + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, pathname, mode); if (ziinit.filestream == NULL) return NULL; - + if (append == APPEND_STATUS_CREATEAFTER) - ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + { + /* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */ + if (disk_size > 0) + return NULL; + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + } + + ziinit.filestream_with_CD = ziinit.filestream; + ziinit.append = append; + ziinit.number_disk = 0; + ziinit.number_disk_with_CD = 0; + ziinit.disk_size = disk_size; ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; @@ -878,58 +711,207 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl ziinit.add_position_when_writting_offset = 0; init_linkedlist(&(ziinit.central_dir)); - - zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); - if (zi==NULL) + if (zi == NULL) { ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); return NULL; } - /* now we add file in a zipfile */ -# ifndef NO_ADDFILEINEXISTINGZIP +#ifndef NO_ADDFILEINEXISTINGZIP + /* Add file in a zipfile */ ziinit.globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP) { - // Read and Cache Central Directory Records - err = LoadCentralDirectoryRecord(&ziinit); + /* Read and Cache Central Directory Records */ + central_pos = zip64local_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); + /* disable to allow appending to empty ZIP archive (must be standard zip, not zip64) + if (central_pos == 0) + err = ZIP_ERRNO; + */ + + if(err == ZIP_OK) + { + /* read end of central directory info */ + if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + /* number of this disk */ + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK) + err = ZIP_ERRNO; + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK) + err = ZIP_ERRNO; + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + number_entry = uL; + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + number_entry_CD = uL; + if (number_entry_CD!=number_entry) + err = ZIP_BADZIPFILE; + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + size_central_dir = uL; + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + offset_central_dir = uL; + /* zipfile global comment length */ + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK) + err = ZIP_ERRNO; + + if ((err == ZIP_OK) && ((number_entry_CD == 0xffff) || (offset_central_dir == 0xffffffff))) + { + /* Format should be Zip64, as the central directory or file size is too large */ + central_pos = zip64local_SearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos); + + if (central_pos) + { + ZPOS64_T sizeEndOfCentralDirectory; + + if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK) + err = ZIP_ERRNO; + /* version made by */ + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + /* version needed to extract */ + if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + /* number of this disk */ + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK) + err = ZIP_ERRNO; + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK) + err = ZIP_ERRNO; + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK) + err = ZIP_ERRNO; + /* total number of entries in the central directory */ + if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK) + err = ZIP_ERRNO; + if (number_entry_CD!=number_entry) + err = ZIP_BADZIPFILE; + /* size of the central directory */ + if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK) + err = ZIP_ERRNO; + /* offset of start of central directory with respect to the starting disk number */ + if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK) + err = ZIP_ERRNO; + } + else + err = ZIP_BADZIPFILE; + } + } + + if ((err == ZIP_OK) && (central_pos0) + { + ziinit.globalcomment = (char*)ALLOC(size_comment+1); + if (ziinit.globalcomment) + { + size_comment = ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment); + ziinit.globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + ziinit.add_position_when_writting_offset = byte_before_the_zipfile; + + /* Store central directory in memory */ + size_central_dir_to_read = size_central_dir; + buf_size = SIZEDATA_INDATABLOCK; + buf_read = (void*)ALLOC(buf_size); + + if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, + offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; + + while ((size_central_dir_to_read > 0) && (err == ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uLong)read_this) != read_this) + err = ZIP_ERRNO; + + if (err == ZIP_OK) + err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uLong)read_this); + + size_central_dir_to_read -= read_this; + } + TRYFREE(buf_read); + + ziinit.begin_pos = byte_before_the_zipfile; + ziinit.number_entry = number_entry_CD; + + if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, + offset_central_dir+byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; } if (globalcomment) - { - *globalcomment = ziinit.globalcomment; - } -# endif /* !NO_ADDFILEINEXISTINGZIP*/ + *globalcomment = ziinit.globalcomment; +#endif if (err != ZIP_OK) { -# ifndef NO_ADDFILEINEXISTINGZIP +#ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(ziinit.globalcomment); -# endif /* !NO_ADDFILEINEXISTINGZIP*/ +#endif TRYFREE(zi); return NULL; } - else - { - *zi = ziinit; - return (zipFile)zi; - } + + *zi = ziinit; + zipGoToFirstDisk((zipFile)zi); + return(zipFile)zi; } -extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc32_def) { if (pzlib_filefunc32_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill); } - else - return zipOpen3(pathname, append, globalcomment, NULL); + return zipOpen4(pathname, append, 0, globalcomment, NULL); } -extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def) { if (pzlib_filefunc_def != NULL) { @@ -937,150 +919,75 @@ extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; zlib_filefunc64_32_def_fill.ztell32_file = NULL; zlib_filefunc64_32_def_fill.zseek32_file = NULL; - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill); } - else - return zipOpen3(pathname, append, globalcomment, NULL); + return zipOpen4(pathname, append, 0, globalcomment, NULL); } - - -extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +extern zipFile ZEXPORT zipOpen3(const char *pathname, int append, ZPOS64_T disk_size, zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc32_def) { - return zipOpen3((const void*)pathname,append,NULL,NULL); + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill); + } + return zipOpen4(pathname, append, disk_size, globalcomment, NULL); } -extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +extern zipFile ZEXPORT zipOpen3_64(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def) { - return zipOpen3(pathname,append,NULL,NULL); + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill); + } + return zipOpen4(pathname, append, disk_size, globalcomment, NULL); } -int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +extern zipFile ZEXPORT zipOpen(const char* pathname, int append) { - /* write the local header */ - int err; - uInt size_filename = (uInt)strlen(filename); - uInt size_extrafield = size_extrafield_local; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); - - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); - - // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ - } - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); - - if(zi->ci.zip64) - { - size_extrafield += 20; - } - - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); - - if ((err==ZIP_OK) && (size_filename > 0)) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) - err = ZIP_ERRNO; - } - - if ((err==ZIP_OK) && (size_extrafield_local > 0)) - { - if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) - err = ZIP_ERRNO; - } - - - if ((err==ZIP_OK) && (zi->ci.zip64)) - { - // write the Zip64 extended info - short HeaderID = 1; - short DataSize = 16; - ZPOS64_T CompressedSize = 0; - ZPOS64_T UncompressedSize = 0; - - // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) - zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); - - /* err = */ zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); - /* err = */ zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); - - /* err = */ zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); - } - - return err; + return zipOpen3((const void*)pathname,append,0,NULL,NULL); } -/* - NOTE. - When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped - before calling this function it can be done with zipRemoveExtraInfoBlock +extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) +{ + return zipOpen3(pathname,append,0,NULL,NULL); +} - It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize - unnecessary allocations. - */ -extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase, int zip64) +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, + int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64) { zip64_internal* zi; uInt size_filename; - uInt size_comment; + uInt size_comment = 0; uInt i; int err = ZIP_OK; + ZPOS64_T size_available; + ZPOS64_T size_needed; -# ifdef NOCRYPT +#ifdef NOCRYPT + (crcForCrypting); if (password != NULL) return ZIP_PARAMERROR; -# endif +#endif if (file == NULL) return ZIP_PARAMERROR; + if ((method != 0) && #ifdef HAVE_BZIP2 - if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) - return ZIP_PARAMERROR; -#else - if ((method!=0) && (method!=Z_DEFLATED)) - return ZIP_PARAMERROR; + (method != Z_BZIP2ED) && #endif + (method != Z_DEFLATED)) + return ZIP_PARAMERROR; zi = (zip64_internal*)file; @@ -1091,12 +998,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return err; } - if (filename==NULL) - filename="-"; - - if (comment==NULL) - size_comment = 0; - else + if (filename == NULL) + filename = "-"; + if (comment != NULL) size_comment = (uInt)strlen(comment); size_filename = (uInt)strlen(filename); @@ -1108,73 +1012,98 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, if (zipfi->dosDate != 0) zi->ci.dosDate = zipfi->dosDate; else - zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); } - zi->ci.flag = flagBase; - if ((level==8) || (level==9)) - zi->ci.flag |= 2; - if (level==2) - zi->ci.flag |= 4; - if (level==1) - zi->ci.flag |= 6; - if (password != NULL) - zi->ci.flag |= 1; - - zi->ci.crc32 = 0; zi->ci.method = method; + zi->ci.compression_method = method; + zi->ci.crc32 = 0; zi->ci.encrypt = 0; zi->ci.stream_initialised = 0; zi->ci.pos_in_buffered_data = 0; zi->ci.raw = raw; - zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + zi->ci.flag = flagBase; + if ((level == 8) || (level == 9)) + zi->ci.flag |= 2; + if (level == 2) + zi->ci.flag |= 4; + if (level == 1) + zi->ci.flag |= 6; + if (password != NULL) + { + zi->ci.flag |= 1; +#ifdef HAVE_AES + zi->ci.method = AES_METHOD; +#endif + } + if (zi->disk_size > 0) + { + if ((zi->number_disk == 0) && (zi->number_entry == 0)) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)DISKHEADERMAGIC, 4); + + /* Make sure enough space available on current disk for local header */ + zipGetDiskSizeAvailable((zipFile)zi, &size_available); + size_needed = 30 + size_filename + size_extrafield_local; + if (zi->ci.zip64) + size_needed += 20; +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + size_needed += 11; +#endif + if (size_available < size_needed) + zipGoToNextDisk((zipFile)zi); + } + + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream); zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; - zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data - + zi->ci.size_centralExtraFree = 32; /* Extra space reserved for ZIP64 extra info */ +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + zi->ci.size_centralExtraFree += 11; /* Extra space reserved for AES extra info */ +#endif zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); - + zi->ci.number_disk = zi->number_disk; zi->ci.size_centralExtra = size_extrafield_global; - zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); - /* version info */ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); - zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); - zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); - zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); - zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ - zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); - zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); - zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + /* Write central directory header */ + zip64local_putValue_inmemory(zi->ci.central_header, (uLong)CENTRALHEADERMAGIC, 4); + zip64local_putValue_inmemory(zi->ci.central_header+4, (uLong)versionMadeBy, 2); + zip64local_putValue_inmemory(zi->ci.central_header+6, (uLong)20, 2); + zip64local_putValue_inmemory(zi->ci.central_header+8, (uLong)zi->ci.flag, 2); + zip64local_putValue_inmemory(zi->ci.central_header+10, (uLong)zi->ci.method, 2); + zip64local_putValue_inmemory(zi->ci.central_header+12, (uLong)zi->ci.dosDate, 4); + zip64local_putValue_inmemory(zi->ci.central_header+16, (uLong)0, 4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20, (uLong)0, 4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24, (uLong)0, 4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28, (uLong)size_filename, 2); + zip64local_putValue_inmemory(zi->ci.central_header+30, (uLong)size_extrafield_global, 2); + zip64local_putValue_inmemory(zi->ci.central_header+32, (uLong)size_comment, 2); + zip64local_putValue_inmemory(zi->ci.central_header+34, (uLong)zi->ci.number_disk, 2); /*disk nm start*/ + + if (zipfi == NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36, (uLong)0, 2); else - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); - - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + zip64local_putValue_inmemory(zi->ci.central_header+36, (uLong)zipfi->internal_fa, 2); + if (zipfi == NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38, (uLong)0, 4); else - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); - - if(zi->ci.pos_local_header >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + zip64local_putValue_inmemory(zi->ci.central_header+38, (uLong)zipfi->external_fa, 4); + if (zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42, (uLong)0xffffffff, 4); else - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + zip64local_putValue_inmemory(zi->ci.central_header+42, + (uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4); - for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = *(((const char*)extrafield_global)+i); - - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) return ZIP_INTERNALERROR; @@ -1183,7 +1112,100 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, zi->ci.totalUncompressedData = 0; zi->ci.pos_zip64extrainfo = 0; - err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + /* Write the local header */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)LOCALHEADERMAGIC, 4); + + if (err == ZIP_OK) + { + if (zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); /* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)20, 2); /* version needed to extract */ + } + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.flag, 2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.method, 2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.dosDate, 4); + + /* CRC & compressed size & uncompressed size will be filled in later and rewritten later */ + + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* crc 32, unknown */ + if (err == ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* compressed size, unknown */ + } + if (err == ZIP_OK) + { + if(zi->ci.zip64) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); + else /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); + } + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_filename, 2); + if (err == ZIP_OK) + { + ZPOS64_T size_extrafield = size_extrafield_local; + if (zi->ci.zip64) + size_extrafield += 20; +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + size_extrafield += 11; +#endif + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_extrafield,2); + } + if ((err == ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename) + err = ZIP_ERRNO; + } + if ((err == ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + /* Write the Zip64 extended info */ + if ((err == ZIP_OK) && (zi->ci.zip64)) + { + short headerid = 1; + short datasize = 16; + ZPOS64_T compressed_size = 0; + ZPOS64_T uncompressed_size = 0; + + /* Remember position of Zip64 extended info for the local file header. + (needed when we update size after done with file) */ + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc, zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)headerid, 2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)datasize, 2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)uncompressed_size, 8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)compressed_size, 8); + } +#ifdef HAVE_AES + /* Write the AES extended info */ + if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD)) + { + int headerid = 0x9901; + short datasize = 7; + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, headerid, 2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, datasize, 2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'A', 1); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'E', 1); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2); + } +#endif #ifdef HAVE_BZIP2 zi->ci.bstream.avail_in = (uInt)0; @@ -1202,206 +1224,247 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, zi->ci.stream.total_out = 0; zi->ci.stream.data_type = Z_BINARY; -#ifdef HAVE_BZIP2 - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) -#else - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) -#endif + if ((err == ZIP_OK) && (!zi->ci.raw)) { - if(zi->ci.method == Z_DEFLATED) + if (method == Z_DEFLATED) { - zi->ci.stream.zalloc = (alloc_func)0; - zi->ci.stream.zfree = (free_func)0; - zi->ci.stream.opaque = (voidpf)0; + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)zi; - if (windowBits>0) - windowBits = -windowBits; + if (windowBits > 0) + windowBits = -windowBits; - err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); - if (err==Z_OK) - zi->ci.stream_initialised = Z_DEFLATED; + if (err == Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; } - else if(zi->ci.method == Z_BZIP2ED) + else if (method == Z_BZIP2ED) { #ifdef HAVE_BZIP2 - // Init BZip stuff here - zi->ci.bstream.bzalloc = 0; - zi->ci.bstream.bzfree = 0; - zi->ci.bstream.opaque = (voidpf)0; + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; - err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); - if(err == BZ_OK) - zi->ci.stream_initialised = Z_BZIP2ED; + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35); + if (err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; #endif } - } -# ifndef NOCRYPT +#ifndef NOCRYPT zi->ci.crypt_header_size = 0; - if ((err==Z_OK) && (password != NULL)) + if ((err == Z_OK) && (password != NULL)) { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = (const unsigned long *) get_crc_table(); - /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + { + unsigned char passverify[AES_PWVERIFYSIZE]; + unsigned char saltvalue[AES_MAXSALTLENGTH]; + uInt saltlength; - sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); - zi->ci.crypt_header_size = sizeHead; + if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3)) + return Z_ERRNO; - if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE); + + prng_init(entropy_fun, zi->ci.aes_rng); + prng_rand(saltvalue, saltlength, zi->ci.aes_rng); + prng_end(zi->ci.aes_rng); + + fcrypt_init(AES_ENCRYPTIONMODE, password, strlen(password), saltvalue, passverify, &zi->ci.aes_ctx); + + if (ZWRITE64(zi->z_filefunc,zi->filestream,saltvalue,saltlength) != saltlength) + err = ZIP_ERRNO; + if (ZWRITE64(zi->z_filefunc,zi->filestream,passverify,AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE) err = ZIP_ERRNO; - } -# endif - if (err==Z_OK) + zi->ci.crypt_header_size = saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE; + } + else +#endif + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + + zi->ci.pcrc_32_tab = (const unsigned long *)get_crc_table(); + /*init_keys(password, zi->ci.keys, zi->ci.pcrc_32_tab);*/ + + sizeHead = crypthead(password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc, zi->filestream, bufHead, sizeHead) != sizeHead) + err = ZIP_ERRNO; + } + } +#endif + + if (err == Z_OK) zi->in_opened_file_inzip = 1; return err; } -extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase) +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, + int memLevel, int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, versionMadeBy, flagBase, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, + strategy, password, crcForCrypting, versionMadeBy, flagBase, 0); } -extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting) +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, + int memLevel, int strategy, const char* password, uLong crcForCrypting) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, + strategy, password, crcForCrypting, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, int zip64) + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, + int memLevel, int strategy, const char* password, uLong crcForCrypting, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64 (file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw) + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, int zip64) + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int zip64) +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void*extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level) +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void*extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0); } +/* Flushes the write buffer to disk */ +local int zip64FlushWriteBuffer OF((zip64_internal* zi)); local int zip64FlushWriteBuffer(zip64_internal* zi) { - int err=ZIP_OK; + int err = ZIP_OK; + uInt written = 0; + uInt total_written = 0; + uInt write = 0; + uInt max_write = 0; + ZPOS64_T size_available = 0; + if (zi->ci.encrypt != 0) { #ifndef NOCRYPT - uInt i; - int t; - for (i=0;ici.pos_in_buffered_data;i++) - zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + { + fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx); + } + else +#endif + { + uInt i; + int t; + for (i = 0;i < zi->ci.pos_in_buffered_data; i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); + } #endif } - if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) - err = ZIP_ERRNO; + write = zi->ci.pos_in_buffered_data; + do + { + max_write = write; + + if (zi->disk_size > 0) + { + err = zipGetDiskSizeAvailable((zipFile)zi, &size_available); + if (err != ZIP_OK) + return err; + + if (size_available == 0) + { + err = zipGoToNextDisk((zipFile)zi); + if (err != ZIP_OK) + return err; + } + + if (size_available < (ZPOS64_T)max_write) + max_write = (uInt)size_available; + } + + written = ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write); + + if (ZERROR64(zi->z_filefunc,zi->filestream)) + { + err = ZIP_ERRNO; + break; + } + + total_written += written; + write -= written; + } + while (write > 0); + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; #ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED) + if (zi->ci.compression_method == Z_BZIP2ED) { - zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_in_hi32 = 0; + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; } else #endif { - zi->ci.totalUncompressedData += zi->ci.stream.total_in; - zi->ci.stream.total_in = 0; + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; } - zi->ci.pos_in_buffered_data = 0; return err; } -extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +extern int ZEXPORT zipWriteInFileInZip(zipFile file,const void* buf,unsigned int len) { zip64_internal* zi; - int err=ZIP_OK; + int err = ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; @@ -1410,113 +1473,100 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; - zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + zi->ci.crc32 = crc32(zi->ci.crc32, buf, (uInt)len); #ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw)) { - zi->ci.bstream.next_in = (void*)buf; - zi->ci.bstream.avail_in = len; - err = BZ_RUN_OK; + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; - while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) - { - if (zi->ci.bstream.avail_out == 0) + while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0)) { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + else + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; + uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo); + } } - - if(err != BZ_RUN_OK) - break; - - if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; -// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; - } - } - - if(err == BZ_RUN_OK) - err = ZIP_OK; + if (err == BZ_RUN_OK) + err = ZIP_OK; } else #endif { - zi->ci.stream.next_in = (Bytef*)buf; - zi->ci.stream.avail_in = len; + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; - while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) - { - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } + while ((err == ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + if (err != ZIP_OK) + break; - if(err != ZIP_OK) - break; + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong total_out_before = zi->ci.stream.total_out; + err = deflate(&zi->ci.stream, Z_NO_FLUSH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before); + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_NO_FLUSH); - if(uTotalOutBefore > zi->ci.stream.total_out) - { - int bBreak = 0; - bBreak++; - } + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - else - { - uInt copy_this,i; - if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) - copy_this = zi->ci.stream.avail_in; - else - copy_this = zi->ci.stream.avail_out; - - for (i = 0; i < copy_this; i++) - *(((char*)zi->ci.stream.next_out)+i) = - *(((const char*)zi->ci.stream.next_in)+i); - { - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out-= copy_this; - zi->ci.stream.next_in+= copy_this; - zi->ci.stream.next_out+= copy_this; - zi->ci.stream.total_in+= copy_this; - zi->ci.stream.total_out+= copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - }// while(...) + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out -= copy_this; + zi->ci.stream.next_in += copy_this; + zi->ci.stream.next_out += copy_this; + zi->ci.stream.total_in += copy_this; + zi->ci.stream.total_out += copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } } return err; } -extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) { return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); } -extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { zip64_internal* zi; ZPOS64_T compressed_size; uLong invalidValue = 0xffffffff; short datasize = 0; - int err=ZIP_OK; + int err = ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; @@ -1526,363 +1576,273 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s return ZIP_PARAMERROR; zi->ci.stream.avail_in = 0; - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - while (err==ZIP_OK) - { - uLong uTotalOutBefore; - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - /* err = ZIP_ERRNO */; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_FINISH); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - } - else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + if (!zi->ci.raw) { -#ifdef HAVE_BZIP2 - err = BZ_FINISH_OK; - while (err==BZ_FINISH_OK) - { - uLong uTotalOutBefore; - if (zi->ci.bstream.avail_out == 0) + if (zi->ci.compression_method == Z_DEFLATED) { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.bstream.total_out_lo32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); - if(err == BZ_STREAM_END) - err = Z_STREAM_END; - - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); - } - - if(err == BZ_FINISH_OK) - err = ZIP_OK; -#endif - } - - if (err==Z_STREAM_END) - err=ZIP_OK; /* this is normal */ - - if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + while (err == ZIP_OK) + { + uLong total_out_before; + if (zi->ci.stream.avail_out == 0) { - if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) - err = ZIP_ERRNO; + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; } - - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - int tmp_err = deflateEnd(&zi->ci.stream); - if (err == ZIP_OK) - err = tmp_err; - zi->ci.stream_initialised = 0; - } + total_out_before = zi->ci.stream.total_out; + err = deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before); + } + } + else if (zi->ci.compression_method == Z_BZIP2ED) + { #ifdef HAVE_BZIP2 - else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + err = BZ_FINISH_OK; + while (err == BZ_FINISH_OK) + { + uLong total_out_before; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + total_out_before = zi->ci.bstream.total_out_lo32; + err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - total_out_before); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + } + + if (err == Z_STREAM_END) + err = ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err == ZIP_OK)) { - int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); - if (err==ZIP_OK) - err = tmperr; - zi->ci.stream_initialised = 0; + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + } + +#ifdef HAVE_AES + if (zi->ci.method == AES_METHOD) + { + unsigned char authcode[AES_AUTHCODESIZE]; + + fcrypt_end(authcode, &zi->ci.aes_ctx); + + if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE) + err = ZIP_ERRNO; } #endif if (!zi->ci.raw) { + if (zi->ci.compression_method == Z_DEFLATED) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if (zi->ci.compression_method == Z_BZIP2ED) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err == ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + crc32 = (uLong)zi->ci.crc32; uncompressed_size = zi->ci.totalUncompressedData; } + compressed_size = zi->ci.totalCompressedData; - -# ifndef NOCRYPT +#ifndef NOCRYPT compressed_size += zi->ci.crypt_header_size; -# endif +#endif - // update Current Item crc and sizes, - if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + /* Update current item crc and sizes */ + if (compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) { - /*version Made by*/ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); - /*version needed*/ - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); - + zip64local_putValue_inmemory(zi->ci.central_header+4, (uLong)45, 2); /* version made by */ + zip64local_putValue_inmemory(zi->ci.central_header+6, (uLong)45, 2); /* version needed */ } - - zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ - - - if(compressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+16, crc32, 4); /* crc */ + if (compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue, 4); /* compr size */ else - zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ - - /// set internal file attributes field + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size, 4); /* compr size */ if (zi->ci.stream.data_type == Z_ASCII) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); - + zip64local_putValue_inmemory(zi->ci.central_header+36, (uLong)Z_ASCII, 2); /* internal file attrib */ if(uncompressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue, 4); /* uncompr size */ else - zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size, 4); /* uncompr size */ - // Add ZIP64 extra info field for uncompressed size - if(uncompressed_size >= 0xffffffff) - datasize += 8; + /* Add ZIP64 extra info field for uncompressed size */ + if (uncompressed_size >= 0xffffffff) + datasize += 8; + /* Add ZIP64 extra info field for compressed size */ + if (compressed_size >= 0xffffffff) + datasize += 8; + /* Add ZIP64 extra info field for relative offset to local file header of current file */ + if (zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; - // Add ZIP64 extra info field for compressed size - if(compressed_size >= 0xffffffff) - datasize += 8; - - // Add ZIP64 extra info field for relative offset to local file header of current file - if(zi->ci.pos_local_header >= 0xffffffff) - datasize += 8; - - if(datasize > 0) + /* Add Extra Information Header for 'ZIP64 information' */ + if (datasize > 0) { - char* p = NULL; + char* p = zi->ci.central_header + zi->ci.size_centralheader; - if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) - { - // we can not write more data to the buffer that we have room for. - return ZIP_BADZIPFILE; - } + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + return ZIP_BADZIPFILE; - p = zi->ci.central_header + zi->ci.size_centralheader; + zip64local_putValue_inmemory(p, 0x0001, 2); + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); + p += 2; - // Add Extra Information Header for 'ZIP64 information' - zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID - p += 2; - zip64local_putValue_inmemory(p, datasize, 2); // DataSize - p += 2; + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } - if(uncompressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, uncompressed_size, 8); - p += 8; - } + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + zi->ci.size_centralExtra += datasize + 4; - if(compressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, compressed_size, 8); - p += 8; - } - - if(zi->ci.pos_local_header >= 0xffffffff) - { - zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); - /* p += 8 */; - } - - // Update how much extra free space we got in the memory buffer - // and increase the centralheader size so the new ZIP64 fields are included - // ( 4 below is the size of HeaderID and DataSize field ) - zi->ci.size_centralExtraFree -= datasize + 4; - zi->ci.size_centralheader += datasize + 4; - - // Update the extra info size field - zi->ci.size_centralExtra += datasize + 4; - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + zip64local_putValue_inmemory(zi->ci.central_header+30, (uLong)zi->ci.size_centralExtra, 2); } - if (err==ZIP_OK) +#ifdef HAVE_AES + /* Write the AES extended info */ + if (zi->ci.method == AES_METHOD) + { + char* p = zi->ci.central_header + zi->ci.size_centralheader; + + datasize = 7; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + return ZIP_BADZIPFILE; + + zip64local_putValue_inmemory(p, 0x9901, 2); + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); + p += 2; + zip64local_putValue_inmemory(p, AES_VERSION, 2); + p += 2; + zip64local_putValue_inmemory(p, 'A', 1); + p += 1; + zip64local_putValue_inmemory(p, 'E', 1); + p += 1; + zip64local_putValue_inmemory(p, AES_ENCRYPTIONMODE, 1); + p += 1; + zip64local_putValue_inmemory(p, zi->ci.compression_method, 2); + p += 2; + + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + zi->ci.size_centralExtra += datasize + 4; + + zip64local_putValue_inmemory(zi->ci.central_header+30, (uLong)zi->ci.size_centralExtra, 2); + } +#endif + + if (err == ZIP_OK) err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); free(zi->ci.central_header); - if (err==ZIP_OK) + if (err == ZIP_OK) { - // Update the LocalFileHeader with the new values. - + /* Update the LocalFileHeader with the new values. */ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + uLong cur_number_disk = zi->number_disk; - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + + /* Local file header is stored on previous disk, switch to make edits */ + if (zi->ci.number_disk != cur_number_disk) + zipGoToSpecificDisk(file, zi->ci.number_disk, 1); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET) != 0) err = ZIP_ERRNO; - if (err==ZIP_OK) + if (err == ZIP_OK) err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ - if(uncompressed_size >= 0xffffffff) + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) { - if(zi->ci.pos_zip64extrainfo > 0) - { - // Update the size in the ZIP64 extended field. - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); - - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); - } + if (err == ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + if (err == ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal } else { - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); - - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + if (err == ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream,compressed_size, 4); + if (err == ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream,uncompressed_size, 4); } - if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + /* Now switch back again to the disk we were on before */ + if (zi->ci.number_disk != cur_number_disk) + zipGoToSpecificDisk(file, cur_number_disk, 1); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip, ZLIB_FILEFUNC_SEEK_SET) != 0) err = ZIP_ERRNO; } - zi->number_entry ++; + zi->number_entry++; zi->in_opened_file_inzip = 0; return err; } -extern int ZEXPORT zipCloseFileInZip (zipFile file) +extern int ZEXPORT zipCloseFileInZip(zipFile file) { - return zipCloseFileInZipRaw (file,0,0); + return zipCloseFileInZipRaw(file, 0, 0); } -int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) -{ - int err = ZIP_OK; - ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); - - /*num disks*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - /*relative offset*/ - if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); - - /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); - - return err; -} - -int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ - int err = ZIP_OK; - - uLong Zip64DataSize = 44; - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); - - if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? - - if (err==ZIP_OK) /* version made by */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); - - if (err==ZIP_OK) /* version needed */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); - - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); - - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - - if (err==ZIP_OK) /* total number of entries in the central dir */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); - - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); - } - return err; -} -int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ - int err = ZIP_OK; - - /*signature*/ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); - - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); - - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - { - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } - } - - if (err==ZIP_OK) /* total number of entries in the central dir */ - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } - - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); - - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff) - { - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); - } - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); - } - - return err; -} - -int Write_GlobalComment(zip64_internal* zi, const char* global_comment) -{ - int err = ZIP_OK; - uInt size_global_comment = 0; - - if(global_comment != NULL) - size_global_comment = (uInt)strlen(global_comment); - - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); - - if (err == ZIP_OK && size_global_comment > 0) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) - err = ZIP_ERRNO; - } - return err; -} - -extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { zip64_internal* zi; int err = 0; uLong size_centraldir = 0; + uInt size_global_comment = 0; ZPOS64_T centraldir_pos_inzip; ZPOS64_T pos; + int write; if (file == NULL) return ZIP_PARAMERROR; @@ -1890,25 +1850,34 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - } + err = zipCloseFileInZip(file); #ifndef NO_ADDFILEINEXISTINGZIP - if (global_comment==NULL) + if (global_comment == NULL) global_comment = zi->globalcomment; #endif + + if (zi->filestream != zi->filestream_with_CD) + { + if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + if (zi->disk_size > 0) + zi->number_disk_with_CD = zi->number_disk + 1; + zi->filestream = zi->filestream_with_CD; + } - centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream); - if (err==ZIP_OK) + if (err == ZIP_OK) { linkedlist_datablock_internal* ldi = zi->central_dir.first_block; - while (ldi!=NULL) + while (ldi!= NULL) { - if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0)) { - if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block); + if (write != ldi->filled_in_this_block) err = ZIP_ERRNO; } @@ -1916,26 +1885,121 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) ldi = ldi->next_datablock; } } + free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff) - { - ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); - Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); - Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + /* Write the ZIP64 central directory header */ + if (pos >= 0xffffffff || zi->number_entry > 0xffff) + { + ZPOS64_T zip64eocd_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + uLong zip64datasize = 44; + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDHEADERMAGIC, 4); + + /* size of this 'zip64 end of central directory' */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)zip64datasize, 8); + /* version made by */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); + /* version needed */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); + /* number of this disk */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4); + /* number of the disk with the start of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4); + /* total number of entries in the central dir on this disk */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + /* total number of entries in the central dir */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + /* size of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)size_centraldir, 8); + + if (err == ZIP_OK) + { + /* offset of start of central directory with respect to the starting disk number */ + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos, 8); + } + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDLOCHEADERMAGIC, 4); + + /* number of the disk with the start of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4); + /*relative offset to the Zip64EndOfCentralDirectory */ + if (err == ZIP_OK) + { + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, pos, 8); + } + /* number of the disk with the start of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD+1, 4); + } + + /* Write the central directory header */ + + /* signature */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ENDHEADERMAGIC, 4); + /* number of this disk */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2); + /* number of the disk with the start of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2); + /* total number of entries in the central dir on this disk */ + if (err == ZIP_OK) + { + if (zi->number_entry >= 0xffff) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2); + } + /* total number of entries in the central dir */ + if (err == ZIP_OK) + { + if (zi->number_entry >= 0xffff) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2); + } + /* size of the central directory */ + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_centraldir,4); + /* offset of start of central directory with respect to the starting disk number */ + if (err == ZIP_OK) + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffffffff, 4); + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)pos, 4); } - if (err==ZIP_OK) - err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + /* Write global comment */ - if(err == ZIP_OK) - err = Write_GlobalComment(zi, global_comment); - - if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) - if (err == ZIP_OK) + if (global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_global_comment, 2); + if (err == ZIP_OK && global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment) err = ZIP_ERRNO; + } + + if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK)) + err = ZIP_ERRNO; #ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(zi->globalcomment); @@ -1944,61 +2008,3 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) return err; } - -extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) -{ - char* p = pData; - int size = 0; - char* pNewHeader; - char* pTmp; - short header; - short dataSize; - - int retVal = ZIP_OK; - - if(pData == NULL || *dataLen < 4) - return ZIP_PARAMERROR; - - pNewHeader = (char*)ALLOC(*dataLen); - pTmp = pNewHeader; - - while(p < (pData + *dataLen)) - { - header = *(short*)p; - dataSize = *(((short*)p)+1); - - if( header == sHeader ) // Header found. - { - p += dataSize + 4; // skip it. do not copy to temp buffer - } - else - { - // Extra Info block should not be removed, So copy it to the temp buffer. - memcpy(pTmp, p, dataSize + 4); - p += dataSize + 4; - size += dataSize + 4; - } - - } - - if(size < *dataLen) - { - // clean old extra info block. - memset(pData,0, *dataLen); - - // copy the new extra info block over the old - if(size > 0) - memcpy(pData, pNewHeader, size); - - // set the new extra info size - *dataLen = size; - - retVal = ZIP_OK; - } - else - retVal = ZIP_ERRNO; - - TRYFREE(pNewHeader); - - return retVal; -} diff --git a/MiniZip/zip.h b/MiniZip/zip.h old mode 100644 new mode 100755 index 8aaebb6..09160d6 --- a/MiniZip/zip.h +++ b/MiniZip/zip.h @@ -2,39 +2,34 @@ Version 1.1, February 14h, 2010 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - For more info read MiniZip_info.txt + For more info read MiniZip_info.txt - --------------------------------------------------------------------------- + --------------------------------------------------------------------------- Condition of use and distribution are the same than zlib : - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - --------------------------------------------------------------------------- - - Changes - - See header of zip.h + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + --------------------------------------------------------------------------- */ #ifndef _zip12_H @@ -44,8 +39,6 @@ extern "C" { #endif -//#define HAVE_BZIP2 - #ifndef _ZLIB_H #include "zlib.h" #endif @@ -88,272 +81,137 @@ typedef voidp zipFile; /* tm_zip contain date/time info */ typedef struct tm_zip_s { - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ } tm_zip; typedef struct { tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ - + uLong dosDate; /* if dos_date == 0, tmu_date is used */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ } zip_fileinfo; typedef const char* zipcharpc; - #define APPEND_STATUS_CREATE (0) #define APPEND_STATUS_CREATEAFTER (1) #define APPEND_STATUS_ADDINZIP (2) +/***************************************************************************/ +/* Writing a zip file */ + extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); -/* - Create a zipfile. - pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on - an Unix computer "zlib/zlib113.zip". - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ +/* Create a zipfile. -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ + pathname should contain the full pathname (by example, on a Windows XP computer + "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip". -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); + return NULL if zipfile cannot be opened + return zipFile handle if no error -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_def)); + If the file pathname exist and append == APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. (useful if the file contain a self extractor code) + If the file pathname exist and append == APPEND_STATUS_ADDINZIP, we will add files in existing + zip (be sure you don't add file that doesn't exist) -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); + NOTE: There is no delete function into a zipfile. If you want delete file into a zipfile, + you must open a zipfile, and create another. Of course, you can use RAW reading and writing to copy + the file you did not want delete. */ -extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int zip64)); +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, int append, zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) - zip64 is set to 1 if a zip64 extended information block should be added to the local file header. - this MUST be '1' if the uncompressed size is >= 0xffffffff. +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, int append, zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); -*/ +extern zipFile ZEXPORT zipOpen3 OF((const char *pathname, int append, ZPOS64_T disk_size, + zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc_def)); +/* Same as zipOpen2 but allows specification of spanned zip size */ +extern zipFile ZEXPORT zipOpen3_64 OF((const void *pathname, int append, ZPOS64_T disk_size, + zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)); -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level)); +/* Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + extrafield_local buffer to store the local header extra field data, can be NULL + size_extrafield_local size of extrafield_local buffer + extrafield_global buffer to store the global header extra field data, can be NULL + size_extrafield_global size of extrafield_local buffer + comment buffer for comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. */ -extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int zip64)); -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file - */ +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int zip64)); +/* Same as zipOpenNewFileInZip with zip64 support */ -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting)); +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw)); +/* Same as zipOpenNewFileInZip, except if raw=1, we write raw file */ -extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - int zip64 - )); +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int zip64)); +/* Same as zipOpenNewFileInZip3 with zip64 support */ -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, + int strategy, const char* password, uLong crcForCrypting)); +/* Same as zipOpenNewFileInZip2, except + windowBits, memLevel, strategy : see parameter strategy in deflateInit2 password : crypting password (NULL for no crypting) - crcForCrypting : crc of file to compress (needed for crypting) - */ + crcForCrypting : crc of file to compress (needed for crypting) */ -extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase - )); +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, + int strategy, const char* password, uLong crcForCrypting, int zip64)); +/* Same as zipOpenNewFileInZip3 with zip64 support */ +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, + int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase)); +/* Same as zipOpenNewFileInZip3 except versionMadeBy & flag fields */ -extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase, - int zip64 - )); -/* - Same than zipOpenNewFileInZip4, except - versionMadeBy : value for Version made by field - flag : value for flag field (compression level info will be added) - */ +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, + uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, + int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64)); +/* Same as zipOpenNewFileInZip4 with zip64 support */ - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* - Write data in the zipfile -*/ +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void* buf, unsigned len)); +/* Write data in the zipfile */ extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* - Close the current file in the zipfile -*/ +/* Close the current file in the zipfile */ -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, ZPOS64_T uncompressed_size, uLong crc32)); +/* Close the current file in the zipfile, for file opened with parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size */ -extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, - ZPOS64_T uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipClose OF((zipFile file, const char* global_comment)); +/* Close the zipfile */ -/* - Close the current file in the zipfile, for file opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ - -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* - Close the zipfile -*/ - - -extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); -/* - zipRemoveExtraInfoBlock - Added by Mathias Svensson - - Remove extra information block from a extra information data for the local file header or central directory header - - It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. - - 0x0001 is the signature header for the ZIP64 extra information blocks - - usage. - Remove ZIP64 Extra information from a central director extra field data - zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); - - Remove ZIP64 Extra information from a Local File Header extra field data - zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); -*/ +/***************************************************************************/ #ifdef __cplusplus } diff --git a/Objective-Zip.xcodeproj/project.pbxproj b/Objective-Zip.xcodeproj/project.pbxproj index b0cd215..92a0173 100755 --- a/Objective-Zip.xcodeproj/project.pbxproj +++ b/Objective-Zip.xcodeproj/project.pbxproj @@ -28,7 +28,6 @@ 8C6D352110E56A8200B63EFA /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D351110E56A8200B63EFA /* trees.c */; }; 8C6D352210E56A8200B63EFA /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D351310E56A8200B63EFA /* uncompr.c */; }; 8C6D352D10E56A9000B63EFA /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352510E56A9000B63EFA /* ioapi.c */; }; - 8C6D352E10E56A9000B63EFA /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352710E56A9000B63EFA /* mztools.c */; }; 8C6D352F10E56A9000B63EFA /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352910E56A9000B63EFA /* unzip.c */; }; 8C6D353010E56A9000B63EFA /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D352B10E56A9000B63EFA /* zip.c */; }; 8C6D354010E56BD300B63EFA /* ZipFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C6D353F10E56BD300B63EFA /* ZipFile.m */; }; @@ -82,8 +81,6 @@ 8C6D352410E56A9000B63EFA /* crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypt.h; path = MiniZip/crypt.h; sourceTree = ""; }; 8C6D352510E56A9000B63EFA /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ioapi.c; path = MiniZip/ioapi.c; sourceTree = ""; }; 8C6D352610E56A9000B63EFA /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ioapi.h; path = MiniZip/ioapi.h; sourceTree = ""; }; - 8C6D352710E56A9000B63EFA /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mztools.c; path = MiniZip/mztools.c; sourceTree = ""; }; - 8C6D352810E56A9000B63EFA /* mztools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mztools.h; path = MiniZip/mztools.h; sourceTree = ""; }; 8C6D352910E56A9000B63EFA /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unzip.c; path = MiniZip/unzip.c; sourceTree = ""; }; 8C6D352A10E56A9000B63EFA /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unzip.h; path = MiniZip/unzip.h; sourceTree = ""; }; 8C6D352B10E56A9000B63EFA /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = zip.c; path = MiniZip/zip.c; sourceTree = ""; }; @@ -232,8 +229,6 @@ 8C6D352410E56A9000B63EFA /* crypt.h */, 8C6D352510E56A9000B63EFA /* ioapi.c */, 8C6D352610E56A9000B63EFA /* ioapi.h */, - 8C6D352710E56A9000B63EFA /* mztools.c */, - 8C6D352810E56A9000B63EFA /* mztools.h */, 8C6D352910E56A9000B63EFA /* unzip.c */, 8C6D352A10E56A9000B63EFA /* unzip.h */, 8C6D352B10E56A9000B63EFA /* zip.c */, @@ -350,7 +345,6 @@ 8C6D352110E56A8200B63EFA /* trees.c in Sources */, 8C6D352210E56A8200B63EFA /* uncompr.c in Sources */, 8C6D352D10E56A9000B63EFA /* ioapi.c in Sources */, - 8C6D352E10E56A9000B63EFA /* mztools.c in Sources */, 8C6D352F10E56A9000B63EFA /* unzip.c in Sources */, 8C6D353010E56A9000B63EFA /* zip.c in Sources */, 8C6D354010E56BD300B63EFA /* ZipFile.m in Sources */, diff --git a/Objective-Zip/ZipFile.m b/Objective-Zip/ZipFile.m index 5f838ca..4c0445a 100644 --- a/Objective-Zip/ZipFile.m +++ b/Objective-Zip/ZipFile.m @@ -274,7 +274,7 @@ @throw [[[ZipException alloc] initWithReason:reason] autorelease]; } - int err= unzLocateFile(_unzFile, [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], 1); + int err= unzLocateFile(_unzFile, [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], NULL); if (err == UNZ_END_OF_LIST_OF_FILE) return NO;