1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Drop gzip support from CZipReader

This allowed reading concatenated gzip-compressed files as if they were an archive.
Aside from being generally uncommon we literally don't need this.
This commit is contained in:
sfan5 2025-03-29 11:55:40 +01:00
parent ae0f955a0e
commit 785c042f1f
3 changed files with 10 additions and 180 deletions

View file

@ -29,14 +29,13 @@ CArchiveLoaderZIP::CArchiveLoaderZIP(io::IFileSystem *fs) :
//! returns true if the file maybe is able to be loaded by this class
bool CArchiveLoaderZIP::isALoadableFileFormat(const io::path &filename) const
{
return core::hasFileExtension(filename, "zip", "pk3") ||
core::hasFileExtension(filename, "gz", "tgz");
return core::hasFileExtension(filename, "zip", "pk3");
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderZIP::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return (fileType == EFAT_ZIP || fileType == EFAT_GZIP);
return fileType == EFAT_ZIP;
}
//! Creates an archive from the filename
@ -63,18 +62,7 @@ IFileArchive *CArchiveLoaderZIP::createArchive(io::IReadFile *file, bool ignoreC
if (file) {
file->seek(0);
u16 sig;
file->read(&sig, 2);
#ifdef __BIG_ENDIAN__
sig = os::Byteswap::byteswap(sig);
#endif
file->seek(0);
bool isGZip = (sig == 0x8b1f);
archive = new CZipReader(FileSystem, file, ignoreCase, ignorePaths, isGZip);
archive = new CZipReader(FileSystem, file, ignoreCase, ignorePaths);
}
return archive;
}
@ -92,27 +80,21 @@ bool CArchiveLoaderZIP::isALoadableFileFormat(io::IReadFile *file) const
header.Sig = os::Byteswap::byteswap(header.Sig);
#endif
return header.Sig == 0x04034b50 || // ZIP
(header.Sig & 0xffff) == 0x8b1f; // gzip
return header.Sig == 0x04034b50; // ZIP
}
// -----------------------------------------------------------------------------
// zip archive
// -----------------------------------------------------------------------------
CZipReader::CZipReader(IFileSystem *fs, IReadFile *file, bool ignoreCase, bool ignorePaths, bool isGZip) :
CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), FileSystem(fs), File(file), IsGZip(isGZip)
CZipReader::CZipReader(IFileSystem *fs, IReadFile *file, bool ignoreCase, bool ignorePaths) :
CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), FileSystem(fs), File(file)
{
if (File) {
File->grab();
// load file entries
if (IsGZip)
while (scanGZipHeader()) {
}
else
while (scanZipHeader()) {
}
while (scanZipHeader()) {}
sort();
}
@ -127,7 +109,7 @@ CZipReader::~CZipReader()
//! get the archive type
E_FILE_ARCHIVE_TYPE CZipReader::getType() const
{
return IsGZip ? EFAT_GZIP : EFAT_ZIP;
return EFAT_ZIP;
}
const IFileList *CZipReader::getFileList() const
@ -135,105 +117,6 @@ const IFileList *CZipReader::getFileList() const
return this;
}
//! scans for a local header, returns false if there is no more local file header.
//! The gzip file format seems to think that there can be multiple files in a gzip file
//! but none
bool CZipReader::scanGZipHeader()
{
SZipFileEntry entry;
entry.Offset = 0;
memset(&entry.header, 0, sizeof(SZIPFileHeader));
// read header
SGZIPMemberHeader header;
if (File->read(&header, sizeof(SGZIPMemberHeader)) == sizeof(SGZIPMemberHeader)) {
#ifdef __BIG_ENDIAN__
header.sig = os::Byteswap::byteswap(header.sig);
header.time = os::Byteswap::byteswap(header.time);
#endif
// check header value
if (header.sig != 0x8b1f)
return false;
// now get the file info
if (header.flags & EGZF_EXTRA_FIELDS) {
// read lenth of extra data
u16 dataLen;
File->read(&dataLen, 2);
#ifdef __BIG_ENDIAN__
dataLen = os::Byteswap::byteswap(dataLen);
#endif
// skip it
File->seek(dataLen, true);
}
io::path ZipFileName = "";
if (header.flags & EGZF_FILE_NAME) {
c8 c;
File->read(&c, 1);
while (c) {
ZipFileName.append(c);
File->read(&c, 1);
}
} else {
// no file name?
ZipFileName = core::deletePathFromFilename(Path);
// rename tgz to tar or remove gz extension
if (core::hasFileExtension(ZipFileName, "tgz")) {
ZipFileName[ZipFileName.size() - 2] = 'a';
ZipFileName[ZipFileName.size() - 1] = 'r';
} else if (core::hasFileExtension(ZipFileName, "gz")) {
ZipFileName[ZipFileName.size() - 3] = 0;
ZipFileName.validate();
}
}
if (header.flags & EGZF_COMMENT) {
c8 c = 'a';
while (c)
File->read(&c, 1);
}
if (header.flags & EGZF_CRC16)
File->seek(2, true);
// we are now at the start of the data blocks
entry.Offset = File->getPos();
entry.header.FilenameLength = ZipFileName.size();
entry.header.CompressionMethod = header.compressionMethod;
entry.header.DataDescriptor.CompressedSize = (File->getSize() - 8) - File->getPos();
// seek to file end
File->seek(entry.header.DataDescriptor.CompressedSize, true);
// read CRC
File->read(&entry.header.DataDescriptor.CRC32, 4);
// read uncompressed size
File->read(&entry.header.DataDescriptor.UncompressedSize, 4);
#ifdef __BIG_ENDIAN__
entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32);
entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize);
#endif
// now we've filled all the fields, this is just a standard deflate block
addItem(ZipFileName, entry.Offset, entry.header.DataDescriptor.UncompressedSize, false, 0);
FileInfo.push_back(entry);
}
// there's only one block of data in a gzip file
return false;
}
//! scans for a local header, returns false if there is no more local file header.
bool CZipReader::scanZipHeader(bool ignoreGPBits)
{