- fixed: Zips whose central directory cannot be read need to print an error message.

This commit is contained in:
Christoph Oelckers 2015-04-13 22:08:44 +02:00
parent 9f2b3efd13
commit 6fc63daabd

View file

@ -168,7 +168,7 @@ bool FZipFile::Open(bool quiet)
if (centraldir == 0) if (centraldir == 0)
{ {
if (!quiet) Printf("\n%s: ZIP file corrupt!\n", Filename); if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", Filename);
return false; return false;
} }
@ -180,7 +180,7 @@ bool FZipFile::Open(bool quiet)
if (info.NumEntries != info.NumEntriesOnAllDisks || if (info.NumEntries != info.NumEntriesOnAllDisks ||
info.FirstDisk != 0 || info.DiskNumber != 0) info.FirstDisk != 0 || info.DiskNumber != 0)
{ {
if (!quiet) Printf("\n%s: Multipart Zip files are not supported.\n", Filename); if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", Filename);
return false; return false;
} }
@ -188,9 +188,10 @@ bool FZipFile::Open(bool quiet)
Lumps = new FZipLump[NumLumps]; Lumps = new FZipLump[NumLumps];
// Load the entire central directory. Too bad that this contains variable length entries... // Load the entire central directory. Too bad that this contains variable length entries...
void *directory = malloc(LittleLong(info.DirectorySize)); int dirsize = LittleLong(info.DirectorySize);
void *directory = malloc(dirsize);
Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET); Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET);
Reader->Read(directory, LittleLong(info.DirectorySize)); Reader->Read(directory, dirsize);
char *dirptr = (char*)directory; char *dirptr = (char*)directory;
FZipLump *lump_p = Lumps; FZipLump *lump_p = Lumps;
@ -205,6 +206,13 @@ bool FZipFile::Open(bool quiet)
LittleShort(zip_fh->ExtraLength) + LittleShort(zip_fh->ExtraLength) +
LittleShort(zip_fh->CommentLength); LittleShort(zip_fh->CommentLength);
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
{
free(directory);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", Filename);
return false;
}
// skip Directories // skip Directories
if (name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0) if (name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0)
{ {
@ -221,7 +229,7 @@ bool FZipFile::Open(bool quiet)
zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_IMPLODE &&
zip_fh->Method != METHOD_SHRINK) zip_fh->Method != METHOD_SHRINK)
{ {
if (!quiet) Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method); if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method);
skipped++; skipped++;
continue; continue;
} }
@ -229,7 +237,7 @@ bool FZipFile::Open(bool quiet)
zip_fh->Flags = LittleShort(zip_fh->Flags); zip_fh->Flags = LittleShort(zip_fh->Flags);
if (zip_fh->Flags & ZF_ENCRYPTED) if (zip_fh->Flags & ZF_ENCRYPTED)
{ {
if (!quiet) Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars()); if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars());
skipped++; skipped++;
continue; continue;
} }
@ -260,7 +268,7 @@ bool FZipFile::Open(bool quiet)
NumLumps -= skipped; NumLumps -= skipped;
free(directory); free(directory);
if (!quiet) Printf(", %d lumps\n", NumLumps); if (!quiet) Printf(TEXTCOLOR_NORMAL ", %d lumps\n", NumLumps);
PostProcessArchive(&Lumps[0], sizeof(FZipLump)); PostProcessArchive(&Lumps[0], sizeof(FZipLump));
return true; return true;