foxygit / doom Log in
commit 63ca127bf99b58295454bbfd29ba5fa644285847
Author:     Michael Day <mikeguy42@gmail.com>
AuthorDate: Thu Aug 5 23:42:27 2021 -0400
Commit:     Michael Day <mikeguy42@gmail.com>
CommitDate: Thu Aug 5 23:42:27 2021 -0400

    deh: Handle orphan carriage returns

    When encountering carriage returns during DeHacked parsing, sniff the
    next character to see if it's a linefeed. If so, filter out the \r and
    return the \n as before. If it's not a linefeed, return the "orphan" \r.

    Fixes #1375.
---
 src/deh_io.c | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/deh_io.c b/src/deh_io.c
index 4a25941c..78cffed3 100644
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -175,9 +175,16 @@ int DEH_GetCharLump(deh_context_t *context)
 int DEH_GetChar(deh_context_t *context)
 {
     int result = 0;
+    boolean last_was_cr = false;

-    // Read characters, but ignore carriage returns
-    // Essentially this is a DOS->Unix conversion
+    // Track the current line number
+
+    if (context->last_was_newline)
+    {
+        ++context->linenum;
+    }
+
+    // Read characters, converting CRLF to LF

     do
     {
@@ -191,14 +198,27 @@ int DEH_GetChar(deh_context_t *context)
                 result = DEH_GetCharLump(context);
                 break;
         }
-    } while (result == '\r');

-    // Track the current line number
+        // Handle \r characters not paired with \n
+        if (last_was_cr && result != '\n')
+        {
+            switch (context->type)
+            {
+                case DEH_INPUT_FILE:
+                    ungetc(result, context->stream);
+                    break;

-    if (context->last_was_newline)
-    {
-        ++context->linenum;
-    }
+                case DEH_INPUT_LUMP:
+                    --context->input_buffer_pos;
+                    break;
+            }
+
+            return '\r';
+        }
+
+        last_was_cr = result == '\r';
+
+    } while (last_was_cr);

     context->last_was_newline = result == '\n';