- allow loading of zips that have one root folder with all content contained within this folder. This top level's folder name will be stripped out from all file names, unless it is a special name that maps to a known namespace.

This commit is contained in:
Christoph Oelckers 2017-02-26 22:55:36 +01:00
parent f918a9d9a7
commit 8c30ca213d

View file

@ -217,12 +217,66 @@ bool FZipFile::Open(bool quiet)
char *dirptr = (char*)directory;
FZipLump *lump_p = Lumps;
// Check if all files have the same prefix so that this can be stripped out.
FString name0;
for (DWORD i = 0; i < NumLumps; i++)
{
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
int len = LittleShort(zip_fh->NameLength);
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
dirptr += sizeof(FZipCentralDirectoryInfo) +
LittleShort(zip_fh->NameLength) +
LittleShort(zip_fh->ExtraLength) +
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;
}
name.ToLower();
if (i == 0)
{
// check for special names, if one of these gets found this must be treated as a normal zip.
bool isspecial = !name.Compare("flats/") ||
!name.Compare("textures/") ||
!name.Compare("hires/") ||
!name.Compare("sprites/") ||
!name.Compare("voxels/") ||
!name.Compare("colormaps/") ||
!name.Compare("acs/") ||
!name.Compare("voices/") ||
!name.Compare("patches/") ||
!name.Compare("graphics/") ||
!name.Compare("sounds/") ||
!name.Compare("music/");
if (isspecial) break;
name0 = name;
}
else
{
if (name.IndexOf(name0) != 0)
{
name0 = "";
break;
}
}
}
dirptr = (char*)directory;
lump_p = Lumps;
for (DWORD i = 0; i < NumLumps; i++)
{
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
int len = LittleShort(zip_fh->NameLength);
FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len);
if (name0.IsNotEmpty()) name = name.Mid(name0.Len());
dirptr += sizeof(FZipCentralDirectoryInfo) +
LittleShort(zip_fh->NameLength) +
LittleShort(zip_fh->ExtraLength) +