diff --git a/miniunz.c b/miniunz.c index 6ae67fc..3dad5c2 100644 --- a/miniunz.c +++ b/miniunz.c @@ -50,6 +50,13 @@ void miniunz_help() /***************************************************************************/ +typedef struct miniunz_opt_s { + uint8_t extract_without_path; + uint8_t overwrite; +} miniunz_opt; + +/***************************************************************************/ + int32_t miniunz_list(void *handle) { mz_unzip_file *file_info = NULL; @@ -136,7 +143,7 @@ int32_t miniunz_list(void *handle) return MZ_OK; } -int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_path, uint8_t *opt_overwrite, const char *password) +int32_t miniunz_extract_currentfile(void *handle, const char *destination, const char *password, miniunz_opt *options) { mz_unzip_file *file_info = NULL; uint8_t buf[INT16_MAX]; @@ -148,7 +155,7 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa void *stream = NULL; char *match = NULL; char *filename = NULL; - char *write_filename = NULL; + char out_path[512]; char directory[512]; @@ -160,25 +167,30 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa return err; } - // Break apart filename and directory from full path - strncpy(directory, file_info->filename, sizeof(directory)); - match = filename = directory; + match = filename = file_info->filename; while (*match != 0) { if ((*match == '/') || (*match == '\\')) filename = match + 1; match += 1; } - if (filename > directory) - directory[(int32_t)(filename - directory) - 1] = 0; + + // Construct output path + out_path[0] = 0; + if (destination != NULL) + mz_path_combine(out_path, destination, sizeof(out_path)); + if (options->extract_without_path) + mz_path_combine(out_path, filename, sizeof(out_path)); + else + mz_path_combine(out_path, file_info->filename, sizeof(out_path)); // If zip entry is a directory then create it on disk if (*filename == 0) { - if (opt_extract_without_path == 0) + if (options->extract_without_path == 0) { - printf("Creating directory: %s\n", file_info->filename); - mz_make_dir(directory); + printf("Creating directory: %s\n", out_path); + mz_make_dir(out_path); } return err; @@ -192,19 +204,14 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa return err; } - if (opt_extract_without_path) - write_filename = filename; - else - write_filename = file_info->filename; - // Determine if the file should be overwritten or not and ask the user if needed - if ((err == MZ_OK) && (*opt_overwrite == 0) && (mz_file_exists(write_filename))) + if ((err == MZ_OK) && (options->overwrite == 0) && (mz_file_exists(out_path))) { char rep = 0; do { char answer[128]; - printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", write_filename); + printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", out_path); if (scanf("%1s", answer) != 1) exit(EXIT_FAILURE); rep = answer[0]; @@ -216,7 +223,7 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa if (rep == 'N') skip = 1; if (rep == 'A') - *opt_overwrite = 1; + options->overwrite = 1; } mz_stream_os_create(&stream); @@ -225,18 +232,32 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa if ((skip == 0) && (err == MZ_OK)) { // Some zips don't contain directory alone before file - if ((mz_stream_os_open(stream, write_filename, MZ_STREAM_MODE_CREATE) != MZ_OK) && - (opt_extract_without_path == 0) && (filename != file_info->filename)) + if ((mz_stream_os_open(stream, out_path, MZ_STREAM_MODE_CREATE) != MZ_OK) && + (options->extract_without_path == 0) && (filename != file_info->filename)) { + // Create the directory of the output path + strncpy(directory, out_path, sizeof(directory)); + match = directory + strlen(directory) - 1; + while (match > directory) + { + if ((*match == '/') || (*match == '\\')) + { + *match = 0; + break; + } + match -= 1; + } + mz_make_dir(directory); - mz_stream_os_open(stream, write_filename, MZ_STREAM_MODE_CREATE); + + mz_stream_os_open(stream, out_path, MZ_STREAM_MODE_CREATE); } } // Read from the zip, unzip to buffer, and write to disk if (mz_stream_os_is_open(stream) == MZ_OK) { - printf(" Extracting: %s\n", write_filename); + printf(" Extracting: %s\n", out_path); while (1) { read = mz_unzip_entry_read(handle, buf, sizeof(buf)); @@ -261,11 +282,11 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa // Set the time of the file that has been unzipped if (err == MZ_OK) - mz_os_set_file_date(write_filename, file_info->dos_date); + mz_os_set_file_date(out_path, file_info->dos_date); } else { - printf("Error opening %s\n", write_filename); + printf("Error opening %s\n", out_path); } mz_stream_os_delete(&stream); @@ -277,7 +298,7 @@ int32_t miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_pa return err; } -int32_t miniunz_extract_all(void *handle, uint8_t opt_extract_without_path, uint8_t opt_overwrite, const char *password) +int32_t miniunz_extract_all(void *handle, const char *destination, const char *password, miniunz_opt *options) { int16_t err = MZ_OK; @@ -292,7 +313,7 @@ int32_t miniunz_extract_all(void *handle, uint8_t opt_extract_without_path, uint while (err == MZ_OK) { - err = miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password); + err = miniunz_extract_currentfile(handle, destination, password, options); if (err != MZ_OK) break; @@ -309,8 +330,7 @@ int32_t miniunz_extract_all(void *handle, uint8_t opt_extract_without_path, uint return 0; } -int32_t miniunz_extract_onefile(void *handle, const char *filename, uint8_t opt_extract_without_path, - uint8_t opt_overwrite, const char *password) +int32_t miniunz_extract_onefile(void *handle, const char *filename, const char *destination, const char *password, miniunz_opt *options) { if (mz_unzip_locate_entry(handle, filename, NULL) != MZ_OK) { @@ -318,7 +338,7 @@ int32_t miniunz_extract_onefile(void *handle, const char *filename, uint8_t opt_ return 2; } - if (miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password) == MZ_OK) + if (miniunz_extract_currentfile(handle, destination, password, options) == MZ_OK) return 0; return 1; @@ -331,15 +351,13 @@ int main(int argc, const char *argv[]) void *stream = NULL; void *split_stream = NULL; void *open_stream = NULL; + miniunz_opt options; int16_t i = 0; - uint8_t opt_do_list = 0; - uint8_t opt_do_extract = 1; - uint8_t opt_do_extract_withoutpath = 0; - uint8_t opt_overwrite = 0; - uint8_t opt_extractdir = 0; + uint8_t do_list = 0; + uint8_t do_extract = 1; const char *path = NULL; const char *password = NULL; - const char *directory = NULL; + const char *destination = NULL; const char *filename_to_extract = NULL; int err = 0; @@ -350,6 +368,8 @@ int main(int argc, const char *argv[]) miniunz_help(); return 0; } + + memset(&options, 0, sizeof(options)); // Parse command line options for (i = 1; i < argc; i++) @@ -362,21 +382,20 @@ int main(int argc, const char *argv[]) { char c = *(p++); if ((c == 'l') || (c == 'L')) - opt_do_list = 1; + do_list = 1; if ((c == 'v') || (c == 'V')) - opt_do_list = 1; + do_list = 1; if ((c == 'x') || (c == 'X')) - opt_do_extract = 1; + do_extract = 1; if ((c == 'e') || (c == 'E')) - opt_do_extract = opt_do_extract_withoutpath = 1; + do_extract = options.extract_without_path = 1; if ((c == 'o') || (c == 'O')) - opt_overwrite = 1; - if ((c == 'd') || (c == 'D')) + options.overwrite = 1; + if (((c == 'd') || (c == 'D')) && (i + 1 < argc)) { - opt_extractdir = 1; - directory = argv[i + 1]; + destination = argv[i + 1]; + i += 1; } - if (((c == 'p') || (c == 'P')) && (i + 1 < argc)) { password = argv[i + 1]; @@ -389,7 +408,7 @@ int main(int argc, const char *argv[]) if (path == NULL) path = argv[i]; - else if ((filename_to_extract == NULL) && (!opt_extractdir)) + else if ((filename_to_extract == NULL) && (destination == NULL)) filename_to_extract = argv[i]; } @@ -425,22 +444,20 @@ int main(int argc, const char *argv[]) printf("%s opened\n", path); // Process command line options - if (opt_do_list) + if (do_list) { err = miniunz_list(handle); } - else if (opt_do_extract) + else if (do_extract) { - if (directory != NULL) - { - // Create target directory if it doesn't exist - mz_make_dir(directory); - } + // Create target directory if it doesn't exist + if (destination != NULL) + mz_make_dir(destination); if (filename_to_extract == NULL) - err = miniunz_extract_all(handle, opt_do_extract_withoutpath, opt_overwrite, password); + err = miniunz_extract_all(handle, destination, password, &options); else - err = miniunz_extract_onefile(handle, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password); + err = miniunz_extract_onefile(handle, filename_to_extract, destination, password, &options); } mz_unzip_close(handle); diff --git a/minizip.c b/minizip.c index d8af075..01140ea 100755 --- a/minizip.c +++ b/minizip.c @@ -60,10 +60,17 @@ void minizip_help() /***************************************************************************/ -int32_t minizip_add_file(void *handle, const char *path, uint8_t opt_exclude_path, mz_zip_compress *compress_info, mz_zip_crypt *crypt_info) +typedef struct minizip_opt_s { + uint8_t exclude_path; +} minizip_opt; + +/***************************************************************************/ + +int32_t minizip_add_file(void *handle, const char *path, minizip_opt *options, mz_zip_compress *compress_info, mz_zip_crypt *crypt_info) { mz_zip_file file_info = { 0 }; int32_t read = 0; + int32_t written = 0; int16_t err = MZ_OK; int16_t err_close = MZ_OK; void *stream = NULL; @@ -80,7 +87,7 @@ int32_t minizip_add_file(void *handle, const char *path, uint8_t opt_exclude_pat filenameinzip += 1; // Should the file be stored with any path info at all? - if (opt_exclude_path) + if (options->exclude_path) { const char *match = NULL; const char *last_slash = NULL; @@ -132,9 +139,13 @@ int32_t minizip_add_file(void *handle, const char *path, uint8_t opt_exclude_pat if (read == 0) break; - err = mz_zip_entry_write(handle, buf, read); - if (err < 0) + written = mz_zip_entry_write(handle, buf, read); + if (written != read) + { + err = mz_stream_os_error(stream); printf("Error in writing %s in the zip file (%d)\n", filenameinzip, err); + break; + } } while (err == MZ_OK); @@ -154,17 +165,16 @@ int32_t minizip_add_file(void *handle, const char *path, uint8_t opt_exclude_pat return err; } -int32_t minizip_add(void *handle, const char *path, uint8_t opt_exclude_path, mz_zip_compress *compress_info, mz_zip_crypt *crypt_info, uint8_t recursive) +int32_t minizip_add(void *handle, const char *path, minizip_opt *options, mz_zip_compress *compress_info, mz_zip_crypt *crypt_info, uint8_t recursive) { DIR *dir = NULL; struct dirent *entry = NULL; int16_t err = 0; - int16_t full_path_len = 0; char full_path[320]; if (mz_os_is_dir(path) != MZ_OK) - return minizip_add_file(handle, path, opt_exclude_path, compress_info, crypt_info); + return minizip_add_file(handle, path, options, compress_info, crypt_info); dir = mz_os_open_dir(path); @@ -179,16 +189,14 @@ int32_t minizip_add(void *handle, const char *path, uint8_t opt_exclude_path, mz if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - strncpy(full_path, path, sizeof(full_path)); - full_path_len = (int16_t)strlen(full_path); - if (full_path_len > 0 && full_path[full_path_len - 1] != '\\') - strncat(full_path, "\\", sizeof(full_path) - full_path_len - 1); - strncat(full_path, entry->d_name, sizeof(full_path) - full_path_len - 2); + full_path[0] = 0; + mz_path_combine(full_path, path, sizeof(full_path)); + mz_path_combine(full_path, entry->d_name, sizeof(full_path)); if (!recursive && mz_os_is_dir(full_path)) continue; - err = minizip_add(handle, full_path, opt_exclude_path, compress_info, crypt_info, recursive); + err = minizip_add(handle, full_path, options, compress_info, crypt_info, recursive); if (err != MZ_OK) return err; } @@ -205,6 +213,7 @@ int main(int argc, char *argv[]) void *split_stream = NULL; void *open_stream = NULL; char *path = NULL; + minizip_opt options; mz_zip_compress compress_info; mz_zip_crypt crypt_info; int64_t disk_size = 0; @@ -224,6 +233,7 @@ int main(int argc, char *argv[]) return 0; } + memset(&options, 0, sizeof(options)); memset(&compress_info, 0, sizeof(compress_info)); memset(&crypt_info, 0, sizeof(crypt_info)); @@ -251,7 +261,7 @@ int main(int argc, char *argv[]) compress_info.method = MZ_COMPRESS_METHOD_RAW; } if ((c == 'j') || (c == 'J')) - opt_exclude_path = 1; + options.exclude_path = 1; #ifdef HAVE_BZIP2 if ((c == 'b') || (c == 'B')) compress_info.method = MZ_COMPRESS_METHOD_BZIP2; @@ -370,7 +380,7 @@ int main(int argc, char *argv[]) // Go through command line args looking for files to add to zip for (i = path_arg + 1; (i < argc) && (err == MZ_OK); i += 1) - err = minizip_add(handle, argv[i], opt_exclude_path, &compress_info, &crypt_info, 1); + err = minizip_add(handle, argv[i], &options, &compress_info, &crypt_info, 1); err_close = mz_zip_close(handle, NULL, MZ_VERSION_MADEBY); diff --git a/mz_os.c b/mz_os.c index b6527c3..f63abbd 100644 --- a/mz_os.c +++ b/mz_os.c @@ -179,3 +179,26 @@ uint32_t mz_tm_to_dosdate(const struct tm *ptm) return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) | ((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour)); } + +int32_t mz_path_combine(char *path, const char *join, int32_t max_path) +{ + int32_t path_len = 0; + + if (path == NULL || join == NULL || max_path == 0) + return MZ_PARAM_ERROR; + + path_len = strlen(path); + + if (path_len == 0) + { + strncpy(path, join, max_path); + } + else + { + if (path[path_len - 1] != '\\' && path[path_len - 1] != '/') + strncat(path, "/", max_path - path_len - 1); + strncat(path, join, max_path - path_len); + } + + return MZ_OK; +} diff --git a/mz_os.h b/mz_os.h index 48c62b2..7dee777 100644 --- a/mz_os.h +++ b/mz_os.h @@ -43,6 +43,8 @@ time_t mz_dosdate_to_time_t(uint64_t dos_date); // Convert dos date/time format to time_t uint32_t mz_tm_to_dosdate(const struct tm *ptm); // Convert struct tm to dos date/time format +int32_t mz_path_combine(char *path, const char *join, int32_t max_path); +// Combines two paths /***************************************************************************/ diff --git a/mz_os_win32.c b/mz_os_win32.c index 2f412a8..f1f0291 100644 --- a/mz_os_win32.c +++ b/mz_os_win32.c @@ -20,10 +20,20 @@ #include "mz.h" +#include "mz_os.h" #include "mz_os_win32.h" /***************************************************************************/ +typedef struct DIR_int_s { + void *find_handle; + WIN32_FIND_DATAW find_data; + struct dirent entry; + uint8_t end; +} DIR_int; + +/***************************************************************************/ + int32_t mz_win32_rand(uint8_t *buf, int32_t size) { HCRYPTPROV provider; @@ -140,13 +150,6 @@ int16_t mz_win32_make_dir(const char *path) return MZ_OK; } -typedef struct DIR_int_s { - void *find_handle; - WIN32_FIND_DATAW find_data; - struct dirent entry; - uint8_t end; -} DIR_int; - DIR *mz_win32_open_dir(const char *path) { WIN32_FIND_DATAW find_data; @@ -154,16 +157,13 @@ DIR *mz_win32_open_dir(const char *path) wchar_t *path_wide = NULL; uint32_t path_wide_size = 0; int16_t err = 0; - int16_t fixed_path_len = 0; char fixed_path[320]; void *handle = NULL; - strncpy(fixed_path, path, sizeof(fixed_path)); - fixed_path_len = (int16_t)strlen(fixed_path); - if (fixed_path_len > 0 && fixed_path[fixed_path_len - 1] != '\\') - strncat(fixed_path, "\\", sizeof(fixed_path) - fixed_path_len - 1); - strncat(fixed_path, "*", sizeof(fixed_path) - fixed_path_len - 2); + fixed_path[0] = 0; + mz_path_combine(fixed_path, path, sizeof(fixed_path)); + mz_path_combine(fixed_path, "*", sizeof(fixed_path)); path_wide_size = MultiByteToWideChar(CP_UTF8, 0, fixed_path, -1, NULL, 0); path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t)); diff --git a/mz_strm_split.c b/mz_strm_split.c index 885ad98..72ef7d7 100644 --- a/mz_strm_split.c +++ b/mz_strm_split.c @@ -199,6 +199,8 @@ int32_t mz_stream_split_read(void *stream, void *buf, int32_t size) return read; if (read == 0) { + if (split->current_disk < 0) // No more disks to goto + break; err = mz_stream_split_goto_disk(stream, split->current_disk + 1); if (err == MZ_EXIST_ERROR) break; diff --git a/mz_strm_win32.c b/mz_strm_win32.c index 07f96a9..4b0ffb3 100644 --- a/mz_strm_win32.c +++ b/mz_strm_win32.c @@ -214,7 +214,7 @@ int64_t mz_stream_win32_tell(void *stream) win32->error = error; } - return large_pos.LowPart; + return large_pos.QuadPart; } int32_t mz_stream_win32_seek(void *stream, int64_t offset, int32_t origin) diff --git a/mz_unzip.c b/mz_unzip.c index 78bc3d9..79887f0 100644 --- a/mz_unzip.c +++ b/mz_unzip.c @@ -96,10 +96,9 @@ static int32_t mz_unzip_search_cd(void *stream, uint64_t *central_pos) { uint8_t buf[1024 + 4]; uint64_t file_size = 0; - uint64_t back_read = 4; + uint64_t back_read = 0; uint64_t max_back = UINT16_MAX; // maximum size of global comment - uint64_t pos_found = 0; - uint32_t read_size = 0; + uint32_t read_size = sizeof(buf); uint64_t read_pos = 0; uint32_t i = 0; @@ -120,7 +119,6 @@ static int32_t mz_unzip_search_cd(void *stream, uint64_t *central_pos) back_read = max_back; read_pos = file_size - back_read; - read_size = sizeof(buf); if (read_size > (file_size - read_pos)) read_size = (uint32_t)(file_size - read_pos); @@ -425,9 +423,9 @@ static int mz_unzip_entry_read_header(void *handle) unzip->pos_in_central_dir + unzip->byte_before_the_zipfile, MZ_STREAM_SEEK_SET) != MZ_OK) err = MZ_STREAM_ERROR; - // Check the magic if (err == MZ_OK) { + // Check the magic if (mz_stream_read_uint32(unzip->stream, &magic) != MZ_OK) err = MZ_STREAM_ERROR; else if (magic == MZ_ZIP_MAGIC_ENDHEADER || magic == MZ_ZIP_MAGIC_ENDHEADER64) @@ -436,41 +434,44 @@ static int mz_unzip_entry_read_header(void *handle) err = MZ_FORMAT_ERROR; } - // Read central directory header - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.version) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.version_needed) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.flag) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.compression_method) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.dos_date) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.crc) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) - err = MZ_STREAM_ERROR; - unzip->file_info.compressed_size = value32; - if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) - err = MZ_STREAM_ERROR; - unzip->file_info.uncompressed_size = value32; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.filename_size) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.extrafield_size) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.comment_size) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint16(unzip->stream, &value16) != MZ_OK) - err = MZ_STREAM_ERROR; - unzip->file_info.disk_num_start = value16; - if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.internal_fa) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.external_fa) != MZ_OK) - err = MZ_STREAM_ERROR; - if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) - err = MZ_STREAM_ERROR; - unzip->file_info.disk_offset = value32; + if (err == MZ_OK) + { + // Read central directory header + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.version) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.version_needed) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.flag) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.compression_method) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.dos_date) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.crc) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) + err = MZ_STREAM_ERROR; + unzip->file_info.compressed_size = value32; + if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) + err = MZ_STREAM_ERROR; + unzip->file_info.uncompressed_size = value32; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.filename_size) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.extrafield_size) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.comment_size) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint16(unzip->stream, &value16) != MZ_OK) + err = MZ_STREAM_ERROR; + unzip->file_info.disk_num_start = value16; + if (mz_stream_read_uint16(unzip->stream, &unzip->file_info.internal_fa) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint32(unzip->stream, &unzip->file_info.external_fa) != MZ_OK) + err = MZ_STREAM_ERROR; + if (mz_stream_read_uint32(unzip->stream, &value32) != MZ_OK) + err = MZ_STREAM_ERROR; + unzip->file_info.disk_offset = value32; + } #ifdef HAVE_AES unzip->aes_version = 0; @@ -983,10 +984,7 @@ extern int ZEXPORT mz_unzip_goto_first_entry(void *handle) unzip = (mz_unzip*)handle; unzip->pos_in_central_dir = unzip->offset_central_dir; - - if (unzip->size_central_dir == 0) - return MZ_END_OF_LIST; - + return mz_unzip_entry_read_header(handle); } diff --git a/mz_zip.c b/mz_zip.c index 672f72a..dc35867 100755 --- a/mz_zip.c +++ b/mz_zip.c @@ -80,10 +80,9 @@ static int32_t mz_zip_search_cd(void *stream, uint64_t *central_pos) { uint8_t buf[1024 + 4]; uint64_t file_size = 0; - uint64_t back_read = 4; + uint64_t back_read = 0; uint64_t max_back = UINT16_MAX; // maximum size of global comment - uint64_t pos_found = 0; - uint32_t read_size = 0; + uint32_t read_size = sizeof(buf); uint64_t read_pos = 0; uint32_t i = 0; @@ -104,7 +103,6 @@ static int32_t mz_zip_search_cd(void *stream, uint64_t *central_pos) back_read = max_back; read_pos = file_size - back_read; - read_size = sizeof(buf); if (read_size > (file_size - read_pos)) read_size = (uint32_t)(file_size - read_pos);