diff --git a/src/miniz.h b/src/miniz.h index 70a62f87..fe45e0e1 100644 --- a/src/miniz.h +++ b/src/miniz.h @@ -1426,6 +1426,11 @@ MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size); +MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip, + const char *pFilename, + mz_uint flags, + mz_uint64 file_start_ofs, + mz_uint64 archive_size); /* Read an archive from an already opened FILE, beginning at the current file * position. */ @@ -1729,7 +1734,7 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback( mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void *callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, const char *user_extra_data_local, + mz_uint level_and_flags, mz_uint32 ext_attributes, const char *user_extra_data_local, mz_uint user_extra_data_local_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len); @@ -1739,16 +1744,17 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback( /* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, * MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or * just set to MZ_DEFAULT_COMPRESSION. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_file( - mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, - const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); +MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, + const char *pSrc_filename, const void *pComment, + mz_uint16 comment_size, + mz_uint level_and_flags, mz_uint32 ext_attributes); /* Like mz_zip_writer_add_file(), except the file data is read from the * specified FILE stream. */ MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile( mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, - mz_uint16 comment_size, mz_uint level_and_flags, + mz_uint16 comment_size, mz_uint level_and_flags, mz_uint32 ext_attributes, const char *user_extra_data_local, mz_uint user_extra_data_local_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len); #endif @@ -2145,10 +2151,12 @@ int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, mz_stream stream; memset(&stream, 0, sizeof(stream)); +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__) /* In case mz_ulong is 64-bits (argh I hate longs). */ +#else if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; - +#endif stream.next_in = pSource; stream.avail_in = (mz_uint32)source_len; stream.next_out = pDest; @@ -2394,10 +2402,12 @@ int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, int status; memset(&stream, 0, sizeof(stream)); +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__) /* In case mz_ulong is 64-bits (argh I hate longs). */ +#else if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; - +#endif stream.next_in = pSource; stream.avail_in = (mz_uint32)*pSource_len; stream.next_out = pDest; @@ -4965,20 +4975,36 @@ static FILE *mz_fopen(const char *pFilename, const char *pMode) { WCHAR *wFilename = mz_utf8z_to_widechar(pFilename); WCHAR *wMode = mz_utf8z_to_widechar(pMode); FILE *pFile = NULL; - errno_t err = _wfopen_s(&pFile, wFilename, wMode); +#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + pFile = _wfopen(wFilename, wMode); +#else + errno_t err = _wfopen_s(&pFile, wFilename, wMode); +#endif free(wFilename); free(wMode); +#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + return pFile; +#else return err ? NULL : pFile; +#endif } static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { WCHAR *wPath = mz_utf8z_to_widechar(pPath); WCHAR *wMode = mz_utf8z_to_widechar(pMode); FILE *pFile = NULL; + #ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + pFile = _wfreopen(wPath, wMode, pStream); +#else errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream); +#endif free(wPath); free(wMode); +#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN + return pFile; +#else return err ? NULL : pFile; +#endif } #if defined(__MINGW32__) @@ -4997,6 +5023,13 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { } #endif +static int mz_mkdir(const char *pDirname) { + WCHAR *wDirname = mz_utf8z_to_widechar(pDirname); + int res = _wmkdir(wDirname); + free(wDirname); + return res; +} + #ifndef MINIZ_NO_TIME #include #endif @@ -5016,8 +5049,9 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN mz_freopen #define MZ_DELETE_FILE remove +#define MZ_MKDIR(d) mz_mkdir(d) -#elif defined(__WATCOMC__) +#elif defined(__MINGW32__) || defined(__WATCOMC__) #ifndef MINIZ_NO_TIME #include #endif @@ -5032,6 +5066,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove +#define MZ_MKDIR(d) _mkdir(d) #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME @@ -5048,6 +5083,11 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove +#if defined(_WIN32) || defined(_WIN64) +#define MZ_MKDIR(d) _mkdir(d) +#else +#define MZ_MKDIR(d) mkdir(d, 0755) +#endif #elif defined(__USE_LARGEFILE64) /* gcc, clang */ #ifndef MINIZ_NO_TIME @@ -5064,6 +5104,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN(p, m, s) freopen64(p, m, s) #define MZ_DELETE_FILE remove +#define MZ_MKDIR(d) mkdir(d, 0755) #elif defined(__APPLE__) || defined(__FreeBSD__) || \ (defined(__linux__) && defined(__x86_64__)) @@ -5081,6 +5122,7 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN(p, m, s) freopen(p, m, s) #define MZ_DELETE_FILE remove +#define MZ_MKDIR(d) mkdir(d, 0755) #else #pragma message( \ @@ -5104,9 +5146,17 @@ static int mz_stat64(const char *path, struct __stat64 *buffer) { #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove +#define MZ_MKDIR(d) mkdir(d, 0755) #endif /* #ifdef _MSC_VER */ #endif /* #ifdef MINIZ_NO_STDIO */ +#ifndef CHMOD +// Upon successful completion, a value of 0 is returned. +// Otherwise, a value of -1 is returned and errno is set to indicate the error. +// int chmod(const char *path, mode_t mode); +#define CHMOD(f, m) chmod(f, m) +#endif + #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) /* Various ZIP archive enums. To completely avoid cross platform compiler @@ -6123,6 +6173,59 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, return MZ_TRUE; } +mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip, + const char *pFilename, mz_uint flags, + mz_uint64 file_start_ofs, + mz_uint64 archive_size) { + mz_uint64 file_size; + MZ_FILE *pFile; + + if ((!pZip) || (!pFilename) || + ((archive_size) && + (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pFile = MZ_FOPEN(pFilename, "r+b"); + if (!pFile) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + + file_size = archive_size; + if (!file_size) { + if (MZ_FSEEK64(pFile, 0, SEEK_END)) { + MZ_FCLOSE(pFile); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); + } + + file_size = MZ_FTELL64(pFile); + } + + /* TODO: Better sanity check archive_size and the # of actual remaining bytes + */ + + if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) { + MZ_FCLOSE(pFile); + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + } + + if (!mz_zip_reader_init_internal(pZip, flags)) { + MZ_FCLOSE(pFile); + return MZ_FALSE; + } + + pZip->m_zip_type = MZ_ZIP_TYPE_FILE; + pZip->m_pRead = mz_zip_file_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pFile = pFile; + pZip->m_archive_size = file_size; + pZip->m_pState->m_file_archive_start_ofs = file_start_ofs; + + if (!mz_zip_reader_read_central_dir(pZip, flags)) { + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags) { @@ -8687,12 +8790,12 @@ mz_bool mz_zip_writer_add_read_buf_callback( mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void *callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, const char *user_extra_data, + mz_uint level_and_flags, mz_uint32 ext_attributes, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { mz_uint16 gen_flags; mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; - mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; + mz_uint16 method = 0, dos_time = 0, dos_date = 0; mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; size_t archive_name_size; @@ -9083,12 +9186,12 @@ static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, mz_bool mz_zip_writer_add_cfile( mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, - mz_uint16 comment_size, mz_uint level_and_flags, + mz_uint16 comment_size, mz_uint level_and_flags,mz_uint32 ext_attributes, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { return mz_zip_writer_add_read_buf_callback( pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, - pFile_time, pComment, comment_size, level_and_flags, user_extra_data, + pFile_time, pComment, comment_size, level_and_flags, ext_attributes,user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); } @@ -9096,7 +9199,7 @@ mz_bool mz_zip_writer_add_cfile( mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags) { + mz_uint level_and_flags, mz_uint32 ext_attributes) { MZ_FILE *pSrc_file = NULL; mz_uint64 uncomp_size = 0; MZ_TIME_T file_modified_time; @@ -9121,7 +9224,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, - level_and_flags, NULL, 0, NULL, 0); + level_and_flags, ext_attributes, NULL, 0, NULL, 0); MZ_FCLOSE(pSrc_file); diff --git a/src/zip.c b/src/zip.c index d35cd4ce..f2d64d1f 100644 --- a/src/zip.c +++ b/src/zip.c @@ -13,19 +13,19 @@ #include #include -#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ +#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ defined(__MINGW32__) /* Win32, DOS, MSVC, MSVS */ #include -#define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \ +#define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \ (P)[1] == ':') #define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE(P) ? 2 : 0) #else -#include // needed for symlink() +#include // needed for symlink() #endif @@ -63,12 +63,12 @@ #define ISSLASH(C) ((C) == '/' || (C) == '\\') #endif -#define CLEANUP(ptr) \ - do { \ - if (ptr) { \ - free((void *)ptr); \ - ptr = NULL; \ - } \ +#define CLEANUP(ptr) \ + do { \ + if (ptr) { \ + free((void *)ptr); \ + ptr = NULL; \ + } \ } while (0) #define UNX_IFDIR 0040000 /* Unix directory */ @@ -172,7 +172,8 @@ static const char *zip_basename(const char *name) { } /* If NAME is all slashes, arrange to return `/'. */ - if (*base == '\0' && ISSLASH(*name) && all_slashes) --base; + if (*base == '\0' && ISSLASH(*name) && all_slashes) + --base; return base; } @@ -192,7 +193,7 @@ static int zip_mkpath(char *path) { } for (p = path + len; *p && len < MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE; p++) { if (ISSLASH(*p) && ((!has_device && len > 0) || (has_device && len > 2))) { -#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ +#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ defined(__MINGW32__) #else if ('\\' == *p) { @@ -200,11 +201,7 @@ static int zip_mkpath(char *path) { } #endif -#if defined(WIN32) - if (_mkdir(npath) == -1) { -#else - if (mkdir(npath, 0777) == -1) { -#endif +if (MZ_MKDIR(npath) == -1) { if (errno != EEXIST) { return ZIP_EMKDIR; } @@ -278,7 +275,7 @@ static char *zip_name_normalize(char *name, char *const nname, size_t len) { if (ISSLASH(c)) { if (ncpy > 0 && !zip_strchr_match(&nname[offn], ncpy, '.')) { offn += ncpy; - nname[offn++] = c; // append '/' + nname[offn++] = c; // append '/' } ncpy = 0; } else { @@ -382,12 +379,12 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, if ((((info.m_version_made_by >> 8) == 3) || ((info.m_version_made_by >> 8) == - 19)) // if zip is produced on Unix or macOS (3 and 19 from - // section 4.4.2.2 of zip standard) + 19)) // if zip is produced on Unix or macOS (3 and 19 from + // section 4.4.2.2 of zip standard) && info.m_external_attr & - (0x20 << 24)) { // and has sym link attribute (0x80 is file, - // 0x40 is directory) -#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ + (0x20 << 24)) { // and has sym link attribute (0x80 is file, + // 0x40 is directory) +#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ defined(__MINGW32__) #else if (info.m_uncomp_size > MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE || @@ -413,11 +410,11 @@ static int zip_archive_extract(mz_zip_archive *zip_archive, const char *dir, } #if defined(_MSC_VER) || defined(PS4) - (void)xattr; // unused + (void)xattr; // unused #else xattr = (info.m_external_attr >> 16) & 0xFFFF; if (xattr > 0 && xattr <= MZ_UINT16_MAX) { - if (chmod(path, (mode_t)xattr) < 0) { + if (CHMOD(path, (mode_t)xattr) < 0) { err = ZIP_ENOPERM; goto out; } @@ -719,7 +716,7 @@ static ssize_t zip_file_move(MZ_FILE *m_pFile, const mz_uint64 to, static ssize_t zip_files_move(struct zip_t *zip, mz_uint64 writen_num, mz_uint64 read_num, size_t length) { ssize_t n = 0; - const size_t page_size = 1 << 12; // 4K + const size_t page_size = 1 << 12; // 4K mz_zip_internal_state *pState = zip->archive.m_pState; mz_uint8 *move_buf = (mz_uint8 *)calloc(1, page_size); @@ -955,7 +952,8 @@ struct zip_t *zip_openwitherror(const char *zipname, int level, char mode, goto cleanup; } - if (level < 0) level = MZ_DEFAULT_LEVEL; + if (level < 0) + level = MZ_DEFAULT_LEVEL; if ((level & 0xF) > MZ_UBER_COMPRESSION) { // Wrong compression level *errnum = ZIP_EINVLVL; @@ -972,56 +970,56 @@ struct zip_t *zip_openwitherror(const char *zipname, int level, char mode, zip->level = (mz_uint)level; zip->entry.index = -1; switch (mode) { - case 'w': - // Create a new archive. - if (!mz_zip_writer_init_file_v2(&(zip->archive), zipname, 0, - MZ_ZIP_FLAG_WRITE_ZIP64)) { - // Cannot initialize zip_archive writer - *errnum = ZIP_EWINIT; - goto cleanup; - } - break; - - case 'r': - if (!mz_zip_reader_init_file_v2( - &(zip->archive), zipname, - zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) { - // An archive file does not exist or cannot initialize - // zip_archive reader - *errnum = ZIP_ERINIT; - goto cleanup; - } - break; - - case 'a': - case 'd': { - MZ_FILE *fp = MZ_FOPEN(zipname, "r+b"); - if (!fp) { - *errnum = ZIP_EOPNFILE; - goto cleanup; - } - if (!mz_zip_reader_init_cfile( - &(zip->archive), fp, 0, - zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { - // An archive file does not exist or cannot initialize zip_archive - // reader - *errnum = ZIP_ERINIT; - fclose(fp); - goto cleanup; - } - if (!mz_zip_writer_init_from_reader_v2(&(zip->archive), zipname, 0)) { - *errnum = ZIP_EWRINIT; - fclose(fp); - mz_zip_reader_end(&(zip->archive)); - goto cleanup; - } - // The file pointer is now owned by the archive object. - zip->archive.m_zip_type = MZ_ZIP_TYPE_FILE; - } break; + case 'w': + // Create a new archive. + if (!mz_zip_writer_init_file_v2(&(zip->archive), zipname, 0, + MZ_ZIP_FLAG_WRITE_ZIP64)) { + // Cannot initialize zip_archive writer + *errnum = ZIP_EWINIT; + goto cleanup; + } + break; + + case 'r': + if (!mz_zip_reader_init_file_v2( + &(zip->archive), zipname, + zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) { + // An archive file does not exist or cannot initialize + // zip_archive reader + *errnum = ZIP_ERINIT; + goto cleanup; + } + break; - default: - *errnum = ZIP_EINVMODE; + case 'a': + case 'd': { + MZ_FILE *fp = MZ_FOPEN(zipname, "r+b"); + if (!fp) { + *errnum = ZIP_EOPNFILE; + goto cleanup; + } + if (!mz_zip_reader_init_cfile( + &(zip->archive), fp, 0, + zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { + // An archive file does not exist or cannot initialize zip_archive + // reader + *errnum = ZIP_ERINIT; + fclose(fp); + goto cleanup; + } + if (!mz_zip_writer_init_from_reader_v2(&(zip->archive), zipname, 0)) { + *errnum = ZIP_EWRINIT; + fclose(fp); + mz_zip_reader_end(&(zip->archive)); goto cleanup; + } + // The file pointer is now owned by the archive object. + zip->archive.m_zip_type = MZ_ZIP_TYPE_FILE; + } break; + + default: + *errnum = ZIP_EINVMODE; + goto cleanup; } return zip; @@ -1062,7 +1060,7 @@ int zip_is64(struct zip_t *zip) { return (int)zip->archive.m_pState->m_zip64; } -int zip_get_archive_offset(struct zip_t *zip, uint64_t *offset) { +int zip_offset(struct zip_t *zip, uint64_t *offset) { if (!zip || !zip->archive.m_pState) { // zip_t handler or zip state is not initialized return ZIP_ENOINIT; @@ -1559,18 +1557,25 @@ int zip_entry_fwrite(struct zip_t *zip, const char *filename) { } #if defined(_WIN32) || defined(__WIN32__) || defined(DJGPP) - (void)modes; // unused + (void)modes; // unused #else /* Initialize with permission bits--which are not implementation-optional */ modes = file_stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); - if (S_ISDIR(file_stat.st_mode)) modes |= UNX_IFDIR; - if (S_ISREG(file_stat.st_mode)) modes |= UNX_IFREG; - if (S_ISLNK(file_stat.st_mode)) modes |= UNX_IFLNK; - if (S_ISBLK(file_stat.st_mode)) modes |= UNX_IFBLK; - if (S_ISCHR(file_stat.st_mode)) modes |= UNX_IFCHR; - if (S_ISFIFO(file_stat.st_mode)) modes |= UNX_IFIFO; - if (S_ISSOCK(file_stat.st_mode)) modes |= UNX_IFSOCK; + if (S_ISDIR(file_stat.st_mode)) + modes |= UNX_IFDIR; + if (S_ISREG(file_stat.st_mode)) + modes |= UNX_IFREG; + if (S_ISLNK(file_stat.st_mode)) + modes |= UNX_IFLNK; + if (S_ISBLK(file_stat.st_mode)) + modes |= UNX_IFBLK; + if (S_ISCHR(file_stat.st_mode)) + modes |= UNX_IFCHR; + if (S_ISFIFO(file_stat.st_mode)) + modes |= UNX_IFIFO; + if (S_ISSOCK(file_stat.st_mode)) + modes |= UNX_IFSOCK; zip->entry.external_attr = (modes << 16) | !(file_stat.st_mode & S_IWUSR); if ((file_stat.st_mode & S_IFMT) == S_IFDIR) { zip->entry.external_attr |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; @@ -1679,7 +1684,7 @@ int zip_entry_fread(struct zip_t *zip, const char *filename) { } #if defined(_MSC_VER) || defined(PS4) - (void)xattr; // unused + (void)xattr; // unused #else if (!mz_zip_reader_file_stat(pzip, idx, &info)) { // Cannot get information about zip archive; @@ -1688,7 +1693,7 @@ int zip_entry_fread(struct zip_t *zip, const char *filename) { xattr = (info.m_external_attr >> 16) & 0xFFFF; if (xattr > 0 && xattr <= MZ_UINT16_MAX) { - if (chmod(filename, (mode_t)xattr) < 0) { + if (CHMOD(filename, (mode_t)xattr) < 0) { return ZIP_ENOPERM; } } @@ -1913,7 +1918,8 @@ struct zip_t *zip_cstream_openwitherror(FILE *stream, int level, char mode, goto cleanup; } - if (level < 0) level = MZ_DEFAULT_LEVEL; + if (level < 0) + level = MZ_DEFAULT_LEVEL; if ((level & 0xF) > MZ_UBER_COMPRESSION) { // Wrong compression level *errnum = ZIP_EINVLVL; @@ -1929,49 +1935,49 @@ struct zip_t *zip_cstream_openwitherror(FILE *stream, int level, char mode, zip->level = (mz_uint)level; switch (mode) { - case 'w': - // Create a new archive. - if (!mz_zip_writer_init_cfile(&(zip->archive), stream, - MZ_ZIP_FLAG_WRITE_ZIP64)) { - // Cannot initialize zip_archive writer - *errnum = ZIP_EWINIT; - goto cleanup; - } - break; - - case 'r': - if (!mz_zip_reader_init_cfile( - &(zip->archive), stream, 0, - zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { - // An archive file does not exist or cannot initialize - // zip_archive reader - *errnum = ZIP_ERINIT; - goto cleanup; - } - break; - - case 'a': - case 'd': - if (!mz_zip_reader_init_cfile( - &(zip->archive), stream, 0, - zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { - // An archive file does not exist or cannot initialize - // zip_archive reader - *errnum = ZIP_ERINIT; + case 'w': + // Create a new archive. + if (!mz_zip_writer_init_cfile(&(zip->archive), stream, + MZ_ZIP_FLAG_WRITE_ZIP64)) { + // Cannot initialize zip_archive writer + *errnum = ZIP_EWINIT; + goto cleanup; + } + break; + + case 'r': + if (!mz_zip_reader_init_cfile( + &(zip->archive), stream, 0, + zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { + // An archive file does not exist or cannot initialize + // zip_archive reader + *errnum = ZIP_ERINIT; + goto cleanup; + } + break; + + case 'a': + case 'd': + if (!mz_zip_reader_init_cfile( + &(zip->archive), stream, 0, + zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) { + // An archive file does not exist or cannot initialize + // zip_archive reader + *errnum = ZIP_ERINIT; + goto cleanup; + } + if ((mode == 'a' || mode == 'd')) { + if (!mz_zip_writer_init_from_reader_v2(&(zip->archive), NULL, 0)) { + *errnum = ZIP_EWRINIT; + mz_zip_reader_end(&(zip->archive)); goto cleanup; } - if ((mode == 'a' || mode == 'd')) { - if (!mz_zip_writer_init_from_reader_v2(&(zip->archive), NULL, 0)) { - *errnum = ZIP_EWRINIT; - mz_zip_reader_end(&(zip->archive)); - goto cleanup; - } - } - break; + } + break; - default: - *errnum = ZIP_EINVMODE; - goto cleanup; + default: + *errnum = ZIP_EINVMODE; + goto cleanup; } return zip; @@ -2025,28 +2031,34 @@ int zip_create(const char *zipname, const char *filenames[], size_t len) { } #if defined(_WIN32) || defined(__WIN32__) || defined(DJGPP) - (void)modes; // unused + (void)modes; // unused #else /* Initialize with permission bits--which are not implementation-optional */ modes = file_stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); - if (S_ISDIR(file_stat.st_mode)) modes |= UNX_IFDIR; - if (S_ISREG(file_stat.st_mode)) modes |= UNX_IFREG; - if (S_ISLNK(file_stat.st_mode)) modes |= UNX_IFLNK; - if (S_ISBLK(file_stat.st_mode)) modes |= UNX_IFBLK; - if (S_ISCHR(file_stat.st_mode)) modes |= UNX_IFCHR; - if (S_ISFIFO(file_stat.st_mode)) modes |= UNX_IFIFO; - if (S_ISSOCK(file_stat.st_mode)) modes |= UNX_IFSOCK; + if (S_ISDIR(file_stat.st_mode)) + modes |= UNX_IFDIR; + if (S_ISREG(file_stat.st_mode)) + modes |= UNX_IFREG; + if (S_ISLNK(file_stat.st_mode)) + modes |= UNX_IFLNK; + if (S_ISBLK(file_stat.st_mode)) + modes |= UNX_IFBLK; + if (S_ISCHR(file_stat.st_mode)) + modes |= UNX_IFCHR; + if (S_ISFIFO(file_stat.st_mode)) + modes |= UNX_IFIFO; + if (S_ISSOCK(file_stat.st_mode)) + modes |= UNX_IFSOCK; ext_attributes = (modes << 16) | !(file_stat.st_mode & S_IWUSR); if ((file_stat.st_mode & S_IFMT) == S_IFDIR) { ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; } #endif - if (!mz_zip_writer_add_file( - &zip_archive, zip_basename(name), name, "", 0, - ZIP_DEFAULT_COMPRESSION_LEVEL | ext_attributes)) { + if (!mz_zip_writer_add_file(&zip_archive, zip_basename(name), name, "", 0, + ZIP_DEFAULT_COMPRESSION_LEVEL, ext_attributes)) { // Cannot add file to zip_archive err = ZIP_ENOFILE; break; diff --git a/src/zip.h b/src/zip.h index 0f870cb3..dce99ffb 100644 --- a/src/zip.h +++ b/src/zip.h @@ -170,7 +170,7 @@ extern ZIP_EXPORT int zip_is64(struct zip_t *zip); * * @return the return code - 0 if successful, negative number (< 0) on error. */ -extern ZIP_EXPORT int zip_get_archive_offset(struct zip_t *zip, uint64_t *offset); +extern ZIP_EXPORT int zip_offset(struct zip_t *zip, uint64_t *offset); /** * Opens an entry by name in the zip archive.