Skip to content

Commit

Permalink
Fixed|Deh Reader: Tolerate mid-file EOF characters in DeHackEd patches
Browse files Browse the repository at this point in the history
Seemingly dehacked.exe will ignore EOF characters encountered before
the real end of the file is reached.

A new IgnoreEOF flag was added to DehReader which enables an EOF
tolerant parsing mode (unexpected EOF characters in the patch will
warned about in the log).

This addresses a compatibility issue with various mods such as the
WolfenDoom series.

Also fixed a bug in parser which resulted in it failed to strip any
trailing carriage return characters (benign, due to other handling).
  • Loading branch information
danij-deng committed Sep 11, 2012
1 parent e46bb82 commit 55c76ac
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
4 changes: 3 additions & 1 deletion doomsday/plugins/dehread/include/dehreader.h
Expand Up @@ -37,9 +37,11 @@
enum DehReaderFlag
{
NoInclude = 0x1, ///< Including of other patch files is disabled.
NoText = 0x2 ///< Ignore Text patches.
NoText = 0x2, ///< Ignore Text patches.
IgnoreEOF = 0x4 ///< Ignore unexpected EOF characters in patches.
};
Q_DECLARE_FLAGS(DehReaderFlags, DehReaderFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(DehReaderFlags)

/**
* Parses a text stream as a DeHackEd patch and updates the engine's definition
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/dehread/src/dehread.cpp
Expand Up @@ -84,7 +84,7 @@ static void readLump(lumpnum_t lumpNum)
Con_Message("Applying DeHackEd patch lump #%i \"%s:%s\"...\n", lumpNum,
F_PrettyPath(W_LumpSourceFile(lumpNum)), W_LumpName(lumpNum));

readDehPatch(deh, NoInclude);
readDehPatch(deh, NoInclude | IgnoreEOF);
}

static void readFile(const String& filePath)
Expand All @@ -103,7 +103,7 @@ static void readFile(const String& filePath)

Con_Message("Applying DeHackEd patch file \"%s\"...\n", F_PrettyPath(filePath.toUtf8().constData()));

readDehPatch(deh);
readDehPatch(deh, IgnoreEOF);
}

static void processPatchLumps()
Expand Down
48 changes: 42 additions & 6 deletions doomsday/plugins/dehread/src/dehreader.cpp
Expand Up @@ -67,6 +67,10 @@ using namespace de;
static int stackDepth;
static const int maxIncludeDepth = MAX_OF(0, DEHREADER_INCLUDE_DEPTH_MAX);

/// Mask containing only those reader flags which should be passed from the current
/// parser to any child parsers for file include statements.
static const DehReaderFlag DehReaderFlagsIncludeMask = IgnoreEOF;

/**
* Not exposed outside this source file; use readDehPatch() instead.
*/
Expand Down Expand Up @@ -128,15 +132,38 @@ class DehReader
}
}

bool atRealEnd()
{
return size_t(pos) >= patch.size();
}

bool atEnd()
{
return (size_t(pos) >= patch.size() || patch.at(pos) == '\0');
if(atRealEnd()) return true;
if(!(flags & IgnoreEOF) && patch.at(pos) == '\0') return true;
return false;
}

void advance()
{
if(atEnd()) return;
if(currentChar() == '\n') currentLineNumber++;

// Handle special characters in the input.
char ch = currentChar().toAscii();
switch(ch)
{
case '\0':
if(size_t(pos) != patch.size() - 1)
{
LOG_WARNING("Unexpected EOF encountered on line #%i, ignoring.") << currentLineNumber;
}
break;
case '\n':
currentLineNumber++;
break;
default: break;
}

pos++;
}

Expand All @@ -159,10 +186,19 @@ class DehReader
{
int endOfLine = pos - start;
// Ignore any trailing carriage return.
if(endOfLine > 0 && patch.at(endOfLine - 1) == '\r') endOfLine -= 1;
if(endOfLine > 0 && patch.at(start + endOfLine - 1) == '\r') endOfLine -= 1;

QByteArray rawLine = patch.mid(start, endOfLine);

// When tolerating mid stream EOF characters, we must first
// strip them before doing attempting encoding conversion.
if(flags & IgnoreEOF)
{
rawLine.replace('\0', "");
}

// Extract a copy of this line and move on.
line = String::fromAscii(patch.mid(start, endOfLine));
// Perform encoding conversion for this line and move on.
line = String::fromAscii(rawLine);
if(currentChar() == '\n') advance();
return;
}
Expand Down Expand Up @@ -601,7 +637,7 @@ class DehReader
}
else
{
DehReaderFlags includeFlags = 0;
DehReaderFlags includeFlags = flags & DehReaderFlagsIncludeMask;

if(arg.startsWith("notext ", Qt::CaseInsensitive))
{
Expand Down

0 comments on commit 55c76ac

Please sign in to comment.