# HG changeset patch # User Adam Kaminski # Date 1610908949 18000 # Sun Jan 17 13:42:29 2021 -0500 # Node ID f8e08adf0da7061ff4d24809edbb0209130ddd80 # Parent 410a312e724f768a00217df03b02a44ee612fc0e ZIP or 7Z files containing duplicate lumps won't be loaded and will instead throw a fatal error indicating the issue. This resolves authentication failures that happened when the malformed file was loaded onto a Linux server. diff -r 410a312e724f -r f8e08adf0da7 src/resourcefiles/file_7z.cpp --- a/src/resourcefiles/file_7z.cpp Sun Jan 17 02:11:23 2021 -0500 +++ b/src/resourcefiles/file_7z.cpp Sun Jan 17 13:42:29 2021 -0500 @@ -263,6 +263,7 @@ Lumps = new F7ZLump[NumLumps]; + FString oldName; // [AK] Store the name of the last lump we scanned. F7ZLump *lump_p = Lumps; TArray nameUTF16; TArray nameASCII; @@ -297,12 +298,22 @@ FString name = &nameASCII[0]; name.ToLower(); + // [AK] Check for any duplicate lumps in the file. If we find any, then throw an error. We + // shouldn't be loading any malformed 7z files, as this can lead to authentication issues. + if ((oldName.IsNotEmpty()) && (oldName.CompareNoCase(name) == 0)) + { + I_Error("Couldn't load file %s: duplicate lump '%s' detected.\n", Filename, name.GetChars()); + return false; + } + lump_p->LumpNameSetup(name); lump_p->LumpSize = int(file->Size); lump_p->Owner = this; lump_p->Flags = LUMPF_ZIPFILE; lump_p->Position = i; lump_p->CheckEmbedded(); + + oldName = name; // [AK] lump_p++; } // Resize the lump record array to its actual size diff -r 410a312e724f -r f8e08adf0da7 src/resourcefiles/file_zip.cpp --- a/src/resourcefiles/file_zip.cpp Sun Jan 17 02:11:23 2021 -0500 +++ b/src/resourcefiles/file_zip.cpp Sun Jan 17 13:42:29 2021 -0500 @@ -205,6 +205,7 @@ Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET); Reader->Read(directory, dirsize); + FString oldName; // [AK] Store the name of the last lump we scanned. char *dirptr = (char*)directory; FZipLump *lump_p = Lumps; for (DWORD i = 0; i < NumLumps; i++) @@ -226,12 +227,21 @@ } // skip Directories + if (name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0) { skipped++; continue; } + // [AK] Check for any duplicate lumps in the file. If we find any, then throw an error. We + // shouldn't be loading any malformed zip files, as this can lead to authentication issues. + if ((oldName.IsNotEmpty()) && (oldName.CompareNoCase(name) == 0)) + { + I_Error("Couldn't load file %s: duplicate lump '%s' detected.\n", Filename, name.GetChars()); + return false; + } + // Ignore unknown compression formats zip_fh->Method = LittleShort(zip_fh->Method); if (zip_fh->Method != METHOD_STORED && @@ -274,8 +284,10 @@ memset(lump_p->Name, 0, sizeof(lump_p->Name)); } + oldName = name; // [AK] lump_p++; } + // Resize the lump record array to its actual size NumLumps -= skipped; free(directory);