Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion quazip/unzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,21 @@ extern unzFile unzOpenInternal (voidpf file,
if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
err=UNZ_ERRNO;

/* For ZIP64 archives, we still need to read the comment size from the regular
end of central directory record if it exists */
us.gi.size_comment = 0;
{
ZPOS64_T regular_central_pos = unz64local_SearchCentralDir(&us.z_filefunc, us.filestream);
if (regular_central_pos != 0)
{
/* Found regular end of central directory, read the comment length. Comment length is at offset 20. */
if (ZSEEK64(us.z_filefunc, us.filestream, regular_central_pos + 20, ZLIB_FILEFUNC_SEEK_SET) == 0)
{
/* Read comment length field (2 bytes at offset 20) */
unz64local_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment);
}
}
}
}
else
{
Expand Down Expand Up @@ -2066,7 +2080,23 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
if (uReadThis>s->gi.size_comment)
uReadThis = s->gi.size_comment;

if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
/* For ZIP64 archives, the central_pos points to ZIP64 EOCD, but comment is in regular EOCD */
ZPOS64_T comment_pos = s->central_pos + 22;
if (s->gi.size_comment > 0) {
/* Check if this might be a ZIP64 archive by looking for ZIP64 EOCD signature */
uLong signature = 0;
if (ZSEEK64(s->z_filefunc, s->filestream, s->central_pos, ZLIB_FILEFUNC_SEEK_SET) == 0 &&
unz64local_getLong(&s->z_filefunc, s->filestream, &signature) == UNZ_OK &&
signature == 0x06064b50) {
/* This is ZIP64 EOCD, need to find regular EOCD for comment */
ZPOS64_T regular_eocd_pos = unz64local_SearchCentralDir(&s->z_filefunc, s->filestream);
if (regular_eocd_pos != 0) {
comment_pos = regular_eocd_pos + 22;
}
}
}

if (ZSEEK64(s->z_filefunc,s->filestream,comment_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
return UNZ_ERRNO;

if (uReadThis>0)
Expand Down
9 changes: 9 additions & 0 deletions qztest/testquazipfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ void TestQuaZipFile::zipUnzipLarge()
QFETCH(QString, zipName);
QFETCH(QString, fileName);
QFETCH(long long, size);

QString testComment = "ZIP64 large file test comment";
QFile testFile(zipName);
if (testFile.exists()) {
if (!testFile.remove()) {
Expand All @@ -214,6 +216,8 @@ void TestQuaZipFile::zipUnzipLarge()
QuaZip testZip(&testFile);
testZip.setZip64Enabled(true);
QVERIFY(testZip.open(QuaZip::mdCreate));

testZip.setComment(testComment);
QFile inFile("tmp/" + fileName);
if (!inFile.open(QIODevice::ReadOnly)) {
qDebug("File name: %s", fileName.toUtf8().constData());
Expand Down Expand Up @@ -255,6 +259,11 @@ void TestQuaZipFile::zipUnzipLarge()
// now test unzip
QuaZip testUnzip(&testFile);
QVERIFY(testUnzip.open(QuaZip::mdUnzip));

// Verify comment is preserved in ZIP64 archive (issue #158)
QString readComment = testUnzip.getComment();
QCOMPARE(readComment, testComment);

QVERIFY(testUnzip.goToFirstFile());

QuaZipFileInfo64 info;
Expand Down
Loading