From c02c5efcf6bf533b65c6c4dadbd9236cefffdd02 Mon Sep 17 00:00:00 2001 From: Mike Klaas Date: Wed, 22 Jul 2026 21:36:56 -0700 Subject: [PATCH] Don't crash on long config file lengths (#581) --- src/config.cc | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/config.cc b/src/config.cc index bf49ca1a..184a5c82 100644 --- a/src/config.cc +++ b/src/config.cc @@ -17,7 +17,7 @@ namespace fallout { -#define CONFIG_FILE_MAX_LINE_LENGTH (1024) +#define CONFIG_FILE_MAX_LINE_LENGTH (2048) // The initial number of sections (or key-value) pairs in the config. #define CONFIG_INITIAL_CAPACITY (10) @@ -32,9 +32,10 @@ struct CaseInsensitiveLess { typedef std::set StringSet; static bool configParseLine(Config* config, char* string); -static bool configParseKeyValue(char* string, char* key, char* value); +static bool configParseKeyValue(char* string, std::string& key, std::string& value); static bool configEnsureSectionExists(Config* config, const char* sectionKey); static bool configTrimString(char* string); +static std::string configGetTrimmedString(const char* string); static bool configWriteDb(Config* config, const char* filePath); static bool configWriteStandard(Config* config, const char* filePath); @@ -120,10 +121,10 @@ bool configParseCommandLineArguments(Config* config, int argc, char** argv) *pch = '\0'; - char key[260]; - char value[260]; + std::string key; + std::string value; if (configParseKeyValue(pch + 1, key, value)) { - if (!configSetString(config, sectionKey, key, value)) { + if (!configSetString(config, sectionKey, key.c_str(), value.c_str())) { *pch = ']'; return false; } @@ -683,13 +684,13 @@ static bool configParseLine(Config* config, char* string) } } - char key[260]; - char value[260]; + std::string key; + std::string value; if (!configParseKeyValue(string, key, value)) { return false; } - return configSetString(config, gConfigLastSectionKey, key, value); + return configSetString(config, gConfigLastSectionKey, key.c_str(), value.c_str()); } // Splits "key=value" pair from [string] and copy appropriate parts into [key] @@ -698,9 +699,9 @@ static bool configParseLine(Config* config, char* string) // Both key and value are trimmed. // // 0x42C594 -static bool configParseKeyValue(char* string, char* key, char* value) +static bool configParseKeyValue(char* string, std::string& key, std::string& value) { - if (string == nullptr || key == nullptr || value == nullptr) { + if (string == nullptr) { return false; } @@ -712,14 +713,11 @@ static bool configParseKeyValue(char* string, char* key, char* value) *pch = '\0'; - strcpy(key, string); - strcpy(value, pch + 1); + key = configGetTrimmedString(string); + value = configGetTrimmedString(pch + 1); *pch = '='; - configTrimString(key); - configTrimString(value); - return true; } @@ -791,6 +789,25 @@ static bool configTrimString(char* string) return true; } +static std::string configGetTrimmedString(const char* string) +{ + if (string == nullptr) { + return std::string(); + } + + const char* start = string; + while (isspace(static_cast(*start))) { + start++; + } + + const char* end = start + strlen(start); + while (end > start && isspace(static_cast(*(end - 1)))) { + end--; + } + + return std::string(start, end); +} + // 0x42C718 bool configGetDouble(Config* config, const char* sectionKey, const char* key, double* valuePtr) {