Skip to content

Commit

Permalink
- allow loading Zips where all content is in a subdirectory.
Browse files Browse the repository at this point in the history
The same logic as in GZDoom applies: The root must not have any other content and the subdirectory must contain identifiable game content.
Some handling was also added to strip out macOS resource fork folders because they can contain data that can confuse file detection.
  • Loading branch information
coelckers committed Apr 5, 2021
1 parent bfcedc2 commit fc314b6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
16 changes: 12 additions & 4 deletions source/common/filesystem/file_zip.cpp
Expand Up @@ -233,12 +233,14 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
}

name.ToLower();
if (name.IndexOf("__macosx") == 0)
continue; // skip Apple garbage. At this stage only the root folder matters,
if (i == 0)
{
// check for special names, if one of these gets found this must be treated as a normal zip.
bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size());
if (isspecial) break;
name0 = name;
name0 = name.Left(name.LastIndexOf("/")+1);
}
else
{
Expand All @@ -252,7 +254,7 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
// at least one of the more common definition lumps must be present.
for (auto &p : filter->requiredPrefixes)
{
if (name.IndexOf(name0 + p) == 0)
if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == name.Len() - strlen(p))
{
foundspeciallump = true;
break;
Expand All @@ -272,7 +274,6 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)

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) +
Expand All @@ -284,7 +285,14 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", FileName.GetChars());
return false;
}


if (name.IndexOf("__macosx") == 0 || name.IndexOf("__MACOSX") == 0)
{
skipped++;
continue; // Weed out Apple's resource fork garbage right here because it interferes with safe operation.
}
if (name0.IsNotEmpty()) name = name.Mid(name0.Len());

// skip Directories
if (name.IsEmpty() || (name.Back() == '/' && LittleLong(zip_fh->UncompressedSize) == 0))
{
Expand Down
14 changes: 14 additions & 0 deletions source/core/initfs.cpp
Expand Up @@ -274,6 +274,18 @@ static void DeleteStuff(FileSystem &fileSystem, const TArray<FString>& deletelum
//
//
//==========================================================================
const char* iwad_folders[13] = { "textures/", "hires/", "sounds/", "music/", "maps/" };
const char* iwad_reserved_duke[12] = { ".map", ".con", "menudef", "gldefs", "zscript", "maps/", nullptr };
const char* iwad_reserved_blood[12] = { ".map", ".ini", "menudef", "gldefs", "zscript", "maps/", nullptr };
const char* iwad_reserved_sw[12] = { ".map", "swcustom.txt", "menudef", "gldefs", "zscript", "maps/", nullptr };
const char* iwad_reserved_ex[12] = { ".map", "menudef", "gldefs", "zscript", "maps/", nullptr };

const char** iwad_reserved()
{
return (g_gameType & GAMEFLAG_PSEXHUMED) ? iwad_reserved_ex :
(g_gameType & GAMEFLAG_SW) ? iwad_reserved_sw :
(g_gameType & GAMEFLAG_BLOOD) ? iwad_reserved_blood : iwad_reserved_duke;
}

void InitFileSystem(TArray<GrpEntry>& groups)
{
Expand Down Expand Up @@ -374,6 +386,8 @@ void InitFileSystem(TArray<GrpEntry>& groups)
}
todelete.Append(userConfig.toBeDeleted);
LumpFilterInfo lfi;
for (auto p : iwad_folders) lfi.reservedFolders.Push(p);
for (auto p = iwad_reserved(); *p; p++) lfi.requiredPrefixes.Push(*p);

lfi.dotFilter = LumpFilter;

Expand Down

0 comments on commit fc314b6

Please sign in to comment.