From 6f1422aec54f4da131d7486a06fa66c0730e3bba Mon Sep 17 00:00:00 2001 From: Kevin Caccamo Date: Sun, 15 Jun 2025 05:11:05 -0400 Subject: [PATCH] Attempt to fix KEYCONF reader memory issues Fix Windows-style line-ending assumptions Make inQuote a bool, since that's how it's used Make pointer usage smarter Add more eof checks, since ASan builds will crash without them Use a better name than 'i' Properly truncate ini names of key sections --- src/gamedata/keysections.cpp | 48 ++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/gamedata/keysections.cpp b/src/gamedata/keysections.cpp index 25b71671b..6f3847927 100644 --- a/src/gamedata/keysections.cpp +++ b/src/gamedata/keysections.cpp @@ -99,8 +99,12 @@ CCMD (addkeysection) return; } + FString name(argv[2]); // Limit the ini name to 32 chars - FString name(argv[2], 32); + if (name.Len() > 32) { + DPrintf(DMSG_ERROR, "WARNING: %s is too long as an ini name! The ini name should be 32 bytes or less.\n", &name[0]); + name.Truncate(32); + } for (unsigned i = 0; i < KeySections.Size(); i++) { @@ -170,39 +174,41 @@ void D_LoadWadSettings () while (conf < eof) { - size_t i = 0; + size_t linepos = 0; // Fetch a line to execute command.Clear(); - for (i = 0; conf + i < eof && conf[i] != '\n'; ++i) + for (linepos = 0; (conf + linepos) < eof && conf[linepos] != '\n' && conf[linepos] != '\r'; ++linepos) { - command.Push(conf[i]); + command.Push(conf[linepos]); } - if (i == 0) // Blank line + if (linepos == 0 && conf >= eof) // End of file { - conf++; - continue; + break; } - command.Push(0); - conf += i; - if (conf >= eof || *conf == '\n') + // Increment 'conf' pointer to next line + conf += linepos; + while (conf < eof && (*conf == '\n' || *conf == '\r')) { conf++; } + // Does 'command' have a comment? If so, remove it. // Comments begin with // - char *stop = &command[i - 1]; + char *stop = &command[linepos]; char *comment = &command[0]; - int inQuote = 0; + bool inQuote = false; - if (*stop == '\r') + if (*stop == '\r' || *stop == '\n') { *stop-- = 0; + } while (comment < stop) { + // if (*comment != '\\' && *(comment + 1) == '\"') if (*comment == '\"') { - inQuote ^= 1; + inQuote = !inQuote; } else if (!inQuote && *comment == '/' && *(comment + 1) == '/') { @@ -210,15 +216,15 @@ void D_LoadWadSettings () } comment++; } - if (comment == &command[0]) - { // Comment at line beginning - continue; - } - else if (comment < stop) - { // Comment in middle of line + // 'comment' will either be the end of the string, or the starting + // position of an inline comment. + if ((comment - &command[0]) < linepos) { *comment = 0; + } else { + // Just in case 'comment' is at EOF + command.Push(0); } - + // DPrintf(DMSG_ERROR, "command: %s\n", &command[0]); AddCommandString (&command[0]); } }