From 8c30ca213dc82de729f99d53a1d5fd86ca54afed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 26 Feb 2017 22:55:36 +0100 Subject: [PATCH] - 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. --- src/resourcefiles/file_zip.cpp | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 3ae708823..18f690205 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -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) +