- file system error management refactoring.

This commit is contained in:
Christoph Oelckers 2023-08-18 20:34:12 +02:00
parent 145450a044
commit 1dc47f91c2
19 changed files with 288 additions and 152 deletions

View file

@ -1066,8 +1066,6 @@ set (PCH_SOURCES
common/utility/m_alloc.cpp
common/utility/utf8.cpp
common/utility/palette.cpp
common/utility/files.cpp
common/utility/files_decompress.cpp
common/utility/memarena.cpp
common/utility/cmdlib.cpp
common/utility/configfile.cpp
@ -1084,19 +1082,6 @@ set (PCH_SOURCES
common/thirdparty/libsmackerdec/src/HuffmanVLC.cpp
common/thirdparty/libsmackerdec/src/LogError.cpp
common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp
common/filesystem/filesystem.cpp
common/filesystem/ancientzip.cpp
common/filesystem/file_7z.cpp
common/filesystem/file_grp.cpp
common/filesystem/file_lump.cpp
common/filesystem/file_rff.cpp
common/filesystem/file_wad.cpp
common/filesystem/file_zip.cpp
common/filesystem/file_pak.cpp
common/filesystem/file_whres.cpp
common/filesystem/file_ssi.cpp
common/filesystem/file_directory.cpp
common/filesystem/resourcefile.cpp
common/engine/cycler.cpp
common/engine/d_event.cpp
common/engine/date.cpp
@ -1220,6 +1205,23 @@ set( ZDOOM_SOURCES
common/thirdparty/math/tan.c
common/thirdparty/math/tanh.c
common/thirdparty/math/fastsin.cpp
common/filesystem/filesystem.cpp
common/filesystem/ancientzip.cpp
common/filesystem/file_7z.cpp
common/filesystem/file_grp.cpp
common/filesystem/file_lump.cpp
common/filesystem/file_rff.cpp
common/filesystem/file_wad.cpp
common/filesystem/file_zip.cpp
common/filesystem/file_pak.cpp
common/filesystem/file_whres.cpp
common/filesystem/file_ssi.cpp
common/filesystem/file_directory.cpp
common/filesystem/resourcefile.cpp
common/filesystem/files.cpp
common/filesystem/files_decompress.cpp
)
set( ZDOOM_NONPCH_SOURCES ${ZDOOM_SOURCES} )

View file

@ -310,7 +310,7 @@ int FZipExploder::Explode(unsigned char *out, unsigned int outsize,
len += minMatchLen;
dist++;
if (bIdx + len > outsize) {
throw CExplosionError("Not enough output space");
return -1;
}
if ((unsigned int)dist > bIdx) {
/* Anything before the first input byte is zero. */

View file

@ -1,6 +1,5 @@
#pragma once
#include "files.h"
#include "engineerrors.h"
class FZipExploder
{
@ -42,10 +41,4 @@ public:
int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags);
};
class CExplosionError : public CRecoverableError
{
public:
CExplosionError(const char *message) : CRecoverableError(message) {}
};
int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize);

View file

@ -168,7 +168,7 @@ struct F7ZLump : public FResourceLump
{
int Position;
virtual int FillCache();
virtual int FillCache() override;
};
@ -340,7 +340,11 @@ F7ZFile::~F7ZFile()
int F7ZLump::FillCache()
{
Cache = new char[LumpSize];
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, Cache);
SRes code = static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, Cache);
if (code != SZ_OK)
{
throw FileSystemException("Error %d reading from 7z archive", code);
}
RefCount = 1;
return 1;
}

View file

@ -250,10 +250,13 @@ int FDirectoryLump::FillCache()
Cache = new char[LumpSize];
if (!fr.OpenFile(mFullPath))
{
memset(Cache, 0, LumpSize);
return 0;
throw FileSystemException("unable to open file");
}
auto read = fr.Read(Cache, LumpSize);
if (read != LumpSize)
{
throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize);
}
fr.Read(Cache, LumpSize);
RefCount = 1;
return 1;
}

View file

@ -72,7 +72,7 @@ struct RFFLump
struct FRFFLump : public FUncompressedLump
{
virtual FileReader *GetReader();
virtual int FillCache();
virtual int FillCache() override;
uint32_t IndexNum;

View file

@ -100,13 +100,19 @@ public:
if(Compressed)
{
FileReader lzss;
if (lzss.OpenDecompressor(Owner->Reader, LumpSize, METHOD_LZSS, false, [](const char* err) { I_Error("%s", err); }))
if (lzss.OpenDecompressor(Owner->Reader, LumpSize, METHOD_LZSS, false, true))
{
lzss.Read(Cache, LumpSize);
}
}
else
Owner->Reader.Read(Cache, LumpSize);
{
auto read = Owner->Reader.Read(Cache, LumpSize);
if (read != LumpSize)
{
throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize);
}
}
RefCount = 1;
return 1;

View file

@ -34,6 +34,7 @@
*/
#include <time.h>
#include <stdexcept>
#include "file_zip.h"
#include "cmdlib.h"
@ -49,7 +50,7 @@
//
//==========================================================================
static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags)
static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags, bool exceptions)
{
switch (Method)
{
@ -64,7 +65,7 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L
case METHOD_LZMA:
{
FileReader frz;
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); }))
if (frz.OpenDecompressor(Reader, LumpSize, Method, false, exceptions))
{
frz.Read(Cache, LumpSize);
}
@ -75,7 +76,11 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L
case METHOD_IMPLODE:
{
FZipExploder exploder;
exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags);
if (exploder.Explode((unsigned char*)Cache, LumpSize, Reader, CompressedSize, GPFlags) == -1)
{
// decompression failed so zero the cache.
memset(Cache, 0, LumpSize);
}
break;
}
@ -96,7 +101,7 @@ bool FCompressedBuffer::Decompress(char *destbuffer)
{
FileReader mr;
mr.OpenMemory(mBuffer, mCompressedSize);
return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, mZipFlags);
return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, mZipFlags, false);
}
//-----------------------------------------------------------------------
@ -499,16 +504,7 @@ int FZipLump::FillCache()
Owner->Reader.Seek(Position, FileReader::SeekSet);
Cache = new char[LumpSize];
try
{
UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
}
catch (const CRecoverableError& )
{
// this cannot propagate the exception but also has no means to handle the error message. Damn...
// At least don't return uninitialized memory here.
memset(Cache, 0, LumpSize);
}
UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags, true);
RefCount = 1;
return 1;
}

View file

@ -19,7 +19,7 @@ struct FZipLump : public FResourceLump
unsigned CRC32;
virtual FileReader *GetReader();
virtual int FillCache();
virtual int FillCache() override;
private:
void SetLumpAddress();

View file

@ -39,11 +39,36 @@
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <functional>
#include "basics.h"
#include "m_swap.h"
#include "tarray.h"
class FileSystemException : public std::exception
{
protected:
static const int MAX_FSERRORTEXT = 1024;
char m_Message[MAX_FSERRORTEXT];
public:
FileSystemException(const char* error, ...)
{
va_list argptr;
va_start(argptr, error);
vsnprintf(m_Message, MAX_FSERRORTEXT, error, argptr);
va_end(argptr);
}
FileSystemException(const char* error, va_list argptr)
{
vsnprintf(m_Message, MAX_FSERRORTEXT, error, argptr);
}
char const* what() const noexcept override
{
return m_Message;
}
};
// Zip compression methods, extended by some internal types to be passed to OpenDecompressor
enum
{
@ -172,7 +197,7 @@ public:
bool OpenMemory(const void *mem, Size length); // read directly from the buffer
bool OpenMemoryArray(const void *mem, Size length); // read from a copy of the buffer.
bool OpenMemoryArray(std::function<bool(TArray<uint8_t>&)> getter); // read contents to a buffer and return a reader to it
bool OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, const std::function<void(const char*)>& cb); // creates a decompressor stream. 'seekable' uses a buffered version so that the Seek and Tell methods can be used.
bool OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, bool exceptions = false); // creates a decompressor stream. 'seekable' uses a buffered version so that the Seek and Tell methods can be used.
Size Tell() const
{
@ -306,7 +331,7 @@ public:
class DecompressorBase : public FileReaderInterface
{
std::function<void(const char*)> ErrorCallback = nullptr;
bool exceptions = false;
public:
// These do not work but need to be defined to satisfy the FileReaderInterface.
// They will just error out when called.
@ -314,11 +339,8 @@ public:
long Seek(long offset, int origin) override;
char* Gets(char* strbuf, int len) override;
void DecompressionError(const char* error, ...) const;
void SetErrorCallback(const std::function<void(const char*)>& cb)
{
ErrorCallback = cb;
}
void SetOwnsReader();
void EnableExceptions(bool on) { exceptions = on; }
protected:
FileReader* File = nullptr;

View file

@ -47,25 +47,22 @@
//==========================================================================
//
// I_Error
// DecompressionError
//
// Throw an error that will send us to the console if we are far enough
// along in the startup process.
// Allows catching errors from the decompressor. The default is just to
// return failure from the calling function.
//
//==========================================================================
void DecompressorBase::DecompressionError(const char *error, ...) const
{
const int MAX_ERRORTEXT = 300;
va_list argptr;
char errortext[MAX_ERRORTEXT];
va_start(argptr, error);
vsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr);
if (ErrorCallback != nullptr) ErrorCallback(errortext);
else throw std::runtime_error(errortext);
if (exceptions)
{
va_list argptr;
va_start(argptr, error);
throw FileSystemException(error, argptr);
va_end(argptr);
}
}
long DecompressorBase::Tell () const
@ -103,18 +100,22 @@ class DecompressorZ : public DecompressorBase
{
enum { BUFF_SIZE = 4096 };
bool SawEOF;
bool SawEOF = false;
z_stream Stream;
uint8_t InBuff[BUFF_SIZE];
public:
DecompressorZ (FileReader *file, bool zip, const std::function<void(const char*)>& cb)
: SawEOF(false)
bool Open (FileReader *file, bool zip)
{
if (File != nullptr)
{
DecompressionError("File already open");
return false;
}
int err;
File = file;
SetErrorCallback(cb);
FillBuffer ();
Stream.zalloc = Z_NULL;
@ -126,7 +127,9 @@ public:
if (err != Z_OK)
{
DecompressionError ("DecompressorZ: inflateInit failed: %s\n", M_ZLibError(err).GetChars());
return false;
}
return true;
}
~DecompressorZ ()
@ -138,6 +141,12 @@ public:
{
int err;
if (File == nullptr)
{
DecompressionError("File not open");
return 0;
}
Stream.next_out = (Bytef *)buffer;
Stream.avail_out = len;
@ -153,11 +162,13 @@ public:
if (err != Z_OK && err != Z_STREAM_END)
{
DecompressionError ("Corrupt zlib stream");
return 0;
}
if (Stream.avail_out != 0)
{
DecompressionError ("Ran out of data in zlib stream");
return 0;
}
return len - Stream.avail_out;
@ -194,18 +205,22 @@ class DecompressorBZ2 : public DecompressorBase
{
enum { BUFF_SIZE = 4096 };
bool SawEOF;
bool SawEOF = false;
bz_stream Stream;
uint8_t InBuff[BUFF_SIZE];
public:
DecompressorBZ2 (FileReader *file, const std::function<void(const char*)>& cb)
: SawEOF(false)
bool Open(FileReader *file)
{
if (File != nullptr)
{
DecompressionError("File already open");
return false;
}
int err;
File = file;
SetErrorCallback(cb);
stupidGlobal = this;
FillBuffer ();
@ -218,7 +233,9 @@ public:
if (err != BZ_OK)
{
DecompressionError ("DecompressorBZ2: bzDecompressInit failed: %d\n", err);
return false;
}
return true;
}
~DecompressorBZ2 ()
@ -229,6 +246,12 @@ public:
long Read (void *buffer, long len) override
{
if (File == nullptr)
{
DecompressionError("File not open");
return 0;
}
int err;
stupidGlobal = this;
@ -247,11 +270,13 @@ public:
if (err != BZ_OK && err != BZ_STREAM_END)
{
DecompressionError ("Corrupt bzip2 stream");
return 0;
}
if (Stream.avail_out != 0)
{
DecompressionError ("Ran out of data in bzip2 stream");
return 0;
}
return len - Stream.avail_out;
@ -303,7 +328,7 @@ class DecompressorLZMA : public DecompressorBase
{
enum { BUFF_SIZE = 4096 };
bool SawEOF;
bool SawEOF = false;
CLzmaDec Stream;
size_t Size;
size_t InPos, InSize;
@ -312,13 +337,17 @@ class DecompressorLZMA : public DecompressorBase
public:
DecompressorLZMA (FileReader *file, size_t uncompressed_size, const std::function<void(const char*)>& cb)
: SawEOF(false)
bool Open(FileReader *file, size_t uncompressed_size)
{
if (File != nullptr)
{
DecompressionError("File already open");
return false;
}
uint8_t header[4 + LZMA_PROPS_SIZE];
int err;
File = file;
SetErrorCallback(cb);
Size = uncompressed_size;
OutProcessed = 0;
@ -327,11 +356,13 @@ public:
if (File->Read(header, sizeof(header)) < (long)sizeof(header))
{
DecompressionError("DecompressorLZMA: File too short\n");
return false;
}
if (header[2] + header[3] * 256 != LZMA_PROPS_SIZE)
{
DecompressionError("DecompressorLZMA: LZMA props size is %d (expected %d)\n",
header[2] + header[3] * 256, LZMA_PROPS_SIZE);
return false;
}
FillBuffer();
@ -342,9 +373,11 @@ public:
if (err != SZ_OK)
{
DecompressionError("DecompressorLZMA: LzmaDec_Allocate failed: %d\n", err);
return false;
}
LzmaDec_Init(&Stream);
return true;
}
~DecompressorLZMA ()
@ -354,6 +387,12 @@ public:
long Read (void *buffer, long len) override
{
if (File == nullptr)
{
DecompressionError("File not open");
return 0;
}
int err;
Byte *next_out = (Byte *)buffer;
@ -372,12 +411,14 @@ public:
if (err != SZ_OK)
{
DecompressionError ("Corrupt LZMA stream");
return 0;
}
if (in_processed == 0 && out_processed == 0)
{
if (status != LZMA_STATUS_FINISHED_WITH_MARK)
{
DecompressionError ("Corrupt LZMA stream");
return 0;
}
}
if (InSize == 0 && !SawEOF)
@ -389,11 +430,13 @@ public:
if (err != Z_OK && err != Z_STREAM_END)
{
DecompressionError ("Corrupt LZMA stream");
return 0;
}
if (len != 0)
{
DecompressionError ("Ran out of data in LZMA stream");
return 0;
}
return (long)(next_out - (Byte *)buffer);
@ -540,16 +583,22 @@ class DecompressorLZSS : public DecompressorBase
}
public:
DecompressorLZSS(FileReader *file, const std::function<void(const char*)>& cb) : SawEOF(false)
bool Open(FileReader *file)
{
if (File != nullptr)
{
DecompressionError("File already open");
return false;
}
File = file;
SetErrorCallback(cb);
Stream.State = STREAM_EMPTY;
Stream.WindowData = Stream.InternalBuffer = Stream.Window+WINDOW_SIZE;
Stream.InternalOut = 0;
Stream.AvailIn = 0;
FillBuffer();
return true;
}
~DecompressorLZSS()
@ -604,50 +653,91 @@ public:
};
bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, const std::function<void(const char*)>& cb)
bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, bool exceptions)
{
DecompressorBase *dec = nullptr;
FileReader *p = &parent;
switch (method & ~METHOD_TRANSFEROWNER)
DecompressorBase* dec = nullptr;
try
{
FileReader* p = &parent;
switch (method & ~METHOD_TRANSFEROWNER)
{
case METHOD_DEFLATE:
case METHOD_ZLIB:
dec = new DecompressorZ(p, method == METHOD_DEFLATE, cb);
{
auto idec = new DecompressorZ;
dec = idec;
idec->EnableExceptions(exceptions);
if (!idec->Open(p, method == METHOD_DEFLATE))
{
delete idec;
return false;
}
break;
}
case METHOD_BZIP2:
dec = new DecompressorBZ2(p, cb);
{
auto idec = new DecompressorBZ2;
dec = idec;
idec->EnableExceptions(exceptions);
if (!idec->Open(p))
{
delete idec;
return false;
}
break;
}
case METHOD_LZMA:
dec = new DecompressorLZMA(p, length, cb);
{
auto idec = new DecompressorLZMA;
dec = idec;
idec->EnableExceptions(exceptions);
if (!idec->Open(p, length))
{
delete idec;
return false;
}
break;
}
case METHOD_LZSS:
dec = new DecompressorLZSS(p, cb);
{
auto idec = new DecompressorLZSS;
dec = idec;
idec->EnableExceptions(exceptions);
if (!idec->Open(p))
{
delete idec;
return false;
}
break;
}
// todo: METHOD_IMPLODE, METHOD_SHRINK
default:
return false;
}
if (method & METHOD_TRANSFEROWNER)
{
dec->SetOwnsReader();
}
}
if (method & METHOD_TRANSFEROWNER)
{
dec->SetOwnsReader();
}
dec->Length = (long)length;
if (!seekable)
{
Close();
mReader = dec;
return true;
dec->Length = (long)length;
if (!seekable)
{
Close();
mReader = dec;
return true;
}
else
{
// todo: create a wrapper. for now this fails
delete dec;
return false;
}
}
else
catch (...)
{
// todo: create a wrapper. for now this fails
delete dec;
return false;
if (dec) delete dec;
throw;
}
}

View file

@ -569,7 +569,7 @@ int FileSystem::GetNumForName (const char *name, int space)
i = CheckNumForName (name, space);
if (i == -1)
I_Error ("GetNumForName: %s not found!", name);
throw FileSystemException("GetNumForName: %s not found!", name);
return i;
}
@ -653,7 +653,7 @@ int FileSystem::GetNumForFullName (const char *name)
i = CheckNumForFullName (name);
if (i == -1)
I_Error ("GetNumForFullName: %s not found!", name);
throw FileSystemException("GetNumForFullName: %s not found!", name);
return i;
}
@ -743,7 +743,7 @@ int FileSystem::GetResource (int resid, const char *type, int filenum) const
if (i == -1)
{
I_Error("GetResource: %d of type %s not found!", resid, type);
throw FileSystemException("GetResource: %d of type %s not found!", resid, type);
}
return i;
}
@ -922,19 +922,19 @@ void FileSystem::InitHashChains (void)
LumpShortName& FileSystem::GetShortName(int i)
{
if ((unsigned)i >= NumEntries) I_Error("GetShortName: Invalid index");
if ((unsigned)i >= NumEntries) throw FileSystemException("GetShortName: Invalid index");
return FileInfo[i].shortName;
}
FString& FileSystem::GetLongName(int i)
{
if ((unsigned)i >= NumEntries) I_Error("GetLongName: Invalid index");
if ((unsigned)i >= NumEntries) throw FileSystemException("GetLongName: Invalid index");
return FileInfo[i].longName;
}
void FileSystem::RenameFile(int num, const char* newfn)
{
if ((unsigned)num >= NumEntries) I_Error("RenameFile: Invalid index");
if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index");
FileInfo[num].longName = newfn;
// This does not alter the short name - call GetShortname to do that!
}
@ -1345,7 +1345,7 @@ TArray<uint8_t> FileSystem::GetFileData(int lump, int pad)
if (numread != size)
{
I_Error("GetFileData: only read %ld of %ld on lump %i\n",
throw FileSystemException("GetFileData: only read %ld of %ld on lump %i\n",
numread, size, lump);
}
if (pad > 0) memset(&data[size], 0, pad);
@ -1367,8 +1367,8 @@ void FileSystem::ReadFile (int lump, void *dest)
if (numread != size)
{
I_Error ("W_ReadFile: only read %ld of %ld on lump %i\n",
numread, size, lump);
throw FileSystemException("W_ReadFile: only read %ld of %ld on '%s'\n",
numread, size, GetLongName(lump).GetChars());
}
}
@ -1399,7 +1399,7 @@ FileReader FileSystem::OpenFileReader(int lump)
{
if ((unsigned)lump >= (unsigned)FileInfo.Size())
{
I_Error("OpenFileReader: %u >= NumEntries", lump);
throw FileSystemException("OpenFileReader: %u >= NumEntries", lump);
}
auto rl = FileInfo[lump].lump;
@ -1418,7 +1418,7 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache)
{
if ((unsigned)lump >= (unsigned)FileInfo.Size())
{
I_Error("ReopenFileReader: %u >= NumEntries", lump);
throw FileSystemException("ReopenFileReader: %u >= NumEntries", lump);
}
auto rl = FileInfo[lump].lump;
@ -1619,7 +1619,7 @@ FString::FString (ELumpNum lumpnum)
if (numread != size)
{
I_Error ("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n",
throw FileSystemException("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n",
numread, size, lumpnum, fileSystem.GetFileFullName((int)lumpnum));
}
}

View file

@ -193,7 +193,15 @@ void *FResourceLump::Lock()
}
else if (LumpSize > 0)
{
FillCache();
try
{
FillCache();
}
catch (const FileSystemException& err)
{
// enrich the message with info about this lump.
throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.GetChars(), err.what());
}
}
return Cache;
}
@ -609,7 +617,13 @@ int FUncompressedLump::FillCache()
Owner->Reader.Seek(Position, FileReader::SeekSet);
Cache = new char[LumpSize];
Owner->Reader.Read(Cache, LumpSize);
auto read = Owner->Reader.Read(Cache, LumpSize);
if (read != LumpSize)
{
throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize);
}
RefCount = 1;
return 1;
}
@ -672,11 +686,15 @@ int FExternalLump::FillCache()
if (f.OpenFile(Filename))
{
f.Read(Cache, LumpSize);
auto read = f.Read(Cache, LumpSize);
if (read != LumpSize)
{
throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize);
}
}
else
{
memset(Cache, 0, LumpSize);
throw FileSystemException("unable to open file");
}
RefCount = 1;
return 1;

View file

@ -190,7 +190,7 @@ struct FUncompressedLump : public FResourceLump
int Position;
virtual FileReader *GetReader();
virtual int FillCache();
virtual int FillCache() override;
virtual int GetFileOffset() { return Position; }
};
@ -213,7 +213,7 @@ struct FExternalLump : public FResourceLump
FString Filename;
FExternalLump(const char *_filename, int filesize = -1);
virtual int FillCache();
virtual int FillCache() override;
};

View file

@ -59,13 +59,13 @@ public:
strncpy (m_Message, message, MAX_ERRORTEXT-1);
m_Message[MAX_ERRORTEXT-1] = '\0';
}
void AppendMessage(const char *message)
void AppendMessage(const char *message) noexcept
{
size_t len = strlen(m_Message);
strncpy(m_Message + len, message, MAX_ERRORTEXT - 1 - len);
m_Message[MAX_ERRORTEXT - 1] = '\0';
}
const char *GetMessage (void) const
const char *GetMessage (void) const noexcept
{
if (m_Message[0] != '\0')
return (const char *)m_Message;

View file

@ -1,5 +1,7 @@
#pragma once
#include <string>
int utf8_encode(int32_t codepoint, uint8_t *buffer, int *size);
int utf8_decode(const uint8_t *src, int *size);
int GetCharFromString(const uint8_t *&string);

View file

@ -1233,7 +1233,7 @@ void D_DoomLoop ()
return;
}
}
catch (CRecoverableError &error)
catch (const CRecoverableError &error)
{
if (error.GetMessage ())
{
@ -1241,6 +1241,14 @@ void D_DoomLoop ()
}
D_ErrorCleanup ();
}
catch (const FileSystemException& error) // in case this propagates up to here it should be treated as a recoverable error.
{
if (error.what())
{
Printf(PRINT_NONOTIFY | PRINT_BOLD, "\n%s\n", error.what());
}
D_ErrorCleanup();
}
catch (CVMAbortException &error)
{
error.MaybePrintMessage();

View file

@ -733,45 +733,36 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id)
if (compressed)
{
FileReader zip;
try
if (zip.OpenDecompressor(dalump, -1, METHOD_ZLIB, false, true))
{
if (zip.OpenDecompressor(dalump, -1, METHOD_ZLIB, false, [](const char* err) { I_Error("%s", err); }))
{
LoadZNodes(zip, type);
}
else
{
Printf("Error loading nodes: Corrupt data.\n");
return false;
}
LoadZNodes(zip, type);
return true;
}
catch (const CRecoverableError& err)
else
{
Printf("Error loading nodes: %s.\n", err.what());
ForceNodeBuild = true;
Level->subsectors.Clear();
Level->segs.Clear();
Level->nodes.Clear();
return false;
Printf("Error loading nodes: Corrupt data.\n");
}
}
else
{
LoadZNodes(dalump, type);
return true;
}
return true;
}
catch (CRecoverableError &error)
{
Printf("Error loading nodes: %s\n", error.GetMessage());
ForceNodeBuild = true;
Level->subsectors.Clear();
Level->segs.Clear();
Level->nodes.Clear();
return false;
}
catch (FileSystemException& error)
{
Printf("Error loading nodes: %s\n", error.what());
}
// clean up.
ForceNodeBuild = true;
Level->subsectors.Clear();
Level->segs.Clear();
Level->nodes.Clear();
return false;
}
@ -3349,9 +3340,10 @@ void MapLoader::LoadLightmap(MapData *map)
return;
FileReader fr;
if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, METHOD_ZLIB, false, [](const char* err) { I_Error("%s", err); }))
if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, METHOD_ZLIB, false, false))
return;
int version = fr.ReadInt32();
if (version != 0)
{