From c27c8c232a89edba59f89a73f32f429fabb994da Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 12 Dec 2023 20:35:03 +0100 Subject: [PATCH] handle RFF encryption like compression. This allows simplifiying the code a lot by moving the decrypter to OpenDecompressor and handling it with generic code in the base class. --- src/common/filesystem/include/fs_files.h | 5 +-- src/common/filesystem/source/file_rff.cpp | 33 +++---------------- .../filesystem/source/files_decompress.cpp | 23 +++++++++++-- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 5bc2d77021..c9a0479e6e 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -83,8 +83,9 @@ enum METHOD_LZMA = 14, METHOD_XZ = 95, METHOD_PPMD = 98, - METHOD_LZSS = 1337, // not used in Zips - this is for Console Doom compression - METHOD_ZLIB = 1338, // Zlib stream with header, used by compressed nodes. + METHOD_LZSS = 1337, // not used in Zips - this is for Console Doom compression + METHOD_ZLIB = 1338, // Zlib stream with header, used by compressed nodes. + METHOD_RFFCRYPT = 1339, // not actual compression but can be put in here to make handling easier. METHOD_IMPLODE_MIN = 1000, // having discrete types for these avoids keeping around the GPFlags word in Zips. METHOD_IMPLODE_0 = 1000, METHOD_IMPLODE_2 = 1002, diff --git a/src/common/filesystem/source/file_rff.cpp b/src/common/filesystem/source/file_rff.cpp index ef74d7f83a..cd6ae7a7a6 100644 --- a/src/common/filesystem/source/file_rff.cpp +++ b/src/common/filesystem/source/file_rff.cpp @@ -90,7 +90,7 @@ void BloodCrypt (void *data, int key, int len) // //========================================================================== -class FRFFFile : public FResourceFile +class FRFFFile : public FUncompressedFile { public: @@ -106,7 +106,7 @@ public: //========================================================================== FRFFFile::FRFFFile(const char *filename, FileReader &file, StringPool* sp) -: FResourceFile(filename, file, sp) +: FUncompressedFile(filename, file, sp) { } @@ -139,8 +139,8 @@ bool FRFFFile::Open(LumpFilterInfo*) Entries[i].Method = METHOD_STORED; if (lumps[i].Flags & 0x10) { - Entries[i].Flags = RESFF_COMPRESSED; // flags the lump as not directly usable - Entries[i].Method = METHOD_INVALID; + Entries[i].Flags = RESFF_COMPRESSED; // for purposes of decoding, compression and encryption are equivalent. + Entries[i].Method = METHOD_RFFCRYPT; } else { @@ -168,31 +168,6 @@ bool FRFFFile::Open(LumpFilterInfo*) return true; } -//========================================================================== -// -// Fills the lump cache and performs decryption -// -//========================================================================== -#if 0 -int FRFFLump::FillCache() -{ - int res = FUncompressedLump::FillCache(); - - if (Flags & LUMPF_COMPRESSED) - { - int cryptlen = std::min (LumpSize, 256); - uint8_t *data = (uint8_t *)Cache; - - for (int i = 0; i < cryptlen; ++i) - { - data[i] ^= i >> 1; - } - } - return res; -} -#endif - - //========================================================================== // // File open diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 7af2788bcb..62c85b3a25 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -952,6 +952,24 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b break; } + // While this could be msde a buffering reader it isn't worth the effort because only stock RFFs are encrypted and they do not contain large files. + case METHOD_RFFCRYPT: + { + auto idec = new MemoryArrayReader; + fr = idec; + auto& buffer = idec->GetArray(); + auto bufr = (uint8_t*)buffer.allocate(length); + p->Read(bufr, length); + + Size cryptlen = std::min(length, 256); + + for (Size i = 0; i < cryptlen; ++i) + { + bufr[i] ^= i >> 1; + } + break; + } + default: return false; } @@ -974,13 +992,13 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b mReader = new BufferingReader(fr); } return true; - } + } catch (...) { if (fr) delete fr; throw; } -} + } bool FCompressedBuffer::Decompress(char* destbuffer) @@ -1001,3 +1019,4 @@ bool FCompressedBuffer::Decompress(char* destbuffer) } return false; } +} \ No newline at end of file