#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mz.h"
#include "mz_zip.h"
#include "mz_compat.h"
static void myextract(const char * zip, const char * fn)
{
unz_file_info64 ufi;
unzFile hUnzip;
void * buffer;
int iRead;
int found;
printf("uopen : %p\n", (void *)(hUnzip = unzOpen2_64(zip, NULL)));
// find requested file
printf("ufi1st: %d\n", unzGoToFirstFile(hUnzip));
found = 0;
for(;;)
{
char fnz[256];
printf("ufinfo: %d\n", unzGetCurrentFileInfo64(hUnzip, &ufi, (char *)&fnz, sizeof(fnz) - 1, NULL, 0, NULL, 0));
if(strcmp(fnz, fn) == 0)
{
printf("FOUND!: %s\n", fn);
printf("uoffst: %lld\n", unzGetOffset64(hUnzip));
printf("ufopen: %d\n", unzOpenCurrentFile3(hUnzip, NULL, NULL, 0, NULL));
buffer = malloc(ufi.uncompressed_size);
printf("uread : %d\n", iRead = unzReadCurrentFile(hUnzip, buffer, ufi.uncompressed_size));
printf("READ : %s\n", buffer); /* WITH ZIP64, IT'S RETURNING THE CONTENT OF THE FIRST FILE WHILE POSITIONED ON THE 2ND */
free(buffer);
printf("ufclos: %d\n", unzCloseCurrentFile(hUnzip));
found = 1;
break;
}
printf("ufinxt: %d\n", unzGoToNextFile(hUnzip));
}
if(found == 0)
printf("not found: %s\n", fn);
printf("uclose: %d\n", unzClose(hUnzip));
}
int main(void)
{
int zip64;
// create two .zip files, one regular and one with ZIP64 enabled, with two file entries each
for(zip64 = 0; zip64 <= 1; zip64++)
{
static const unsigned char content1[] = "11.txt-first file";
static const unsigned char content2[] = "22.txt-second file";
zipFile hZip;
zip_fileinfo zfi;
printf("zcreat: %p\n", (void *)(hZip = zipOpen2_64(zip64 ? "test_64.zip" : "test_32.zip", APPEND_STATUS_CREATE, NULL, NULL)));
memset(&zfi, 0, sizeof(zfi));
printf("zaddfi: %d\n", zipOpenNewFileInZip4_64(hZip, "11.txt", &zfi, NULL, 0, NULL, 0, NULL,
MZ_COMPRESS_METHOD_DEFLATE, 6, 0,
-MAX_WBITS, DEF_MEM_LEVEL, 0,
NULL, 0xD7681E40 /* crc of 'content1' */,
0, 0, zip64));
printf("zwrite: %d\n", zipWriteInFileInZip(hZip, content1, sizeof(content1)));
printf("zfclos: %d\n", zipCloseFileInZip(hZip));
printf("zaddfi: %d\n", zipOpenNewFileInZip4_64(hZip, "22.txt", &zfi, NULL, 0, NULL, 0, NULL,
MZ_COMPRESS_METHOD_DEFLATE, 6, 0,
-MAX_WBITS, DEF_MEM_LEVEL, 0,
NULL, 0x7A416084 /* crc of 'content2' */,
0, 0, zip64));
printf("zwrite: %d\n", zipWriteInFileInZip(hZip, content2, sizeof(content2)));
printf("zfclos: %d\n", zipCloseFileInZip(hZip));
printf("zclose: %d\n", zipClose(hZip, NULL));
}
// try extracting the last (= second) file from each .zip
myextract("test_32.zip", "22.txt");
myextract("test_64.zip", "22.txt");
return 0;
}
Expected result is that the content of the second file entry is shown for both files (in the READ : output line).
Actual result is that despite being positioned on the 2nd file, the content of the first file is being returned by unzReadCurrentFile(). After that, unzCloseCurrentFile() returns with -105.
Self-contained example:
Expected result is that the content of the second file entry is shown for both files (in the
READ :output line).Actual result is that despite being positioned on the 2nd file, the content of the first file is being returned by
unzReadCurrentFile(). After that,unzCloseCurrentFile()returns with-105.Regular tools such as
unzipand7zaare correctly reading the second file from both.zipfiles, which suggests that the issue is not with the generated file, but with the reading (unzip) logic of minizip.