mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-23 13:12:49 +00:00
fix: ignore whitespace around config keys and values
"client_location = ../client " or a value with a trailing space is a common setup mistake that surfaces much later as an unrelated error (a missing client folder, a failed database login). Keys and values are now trimmed of spaces, tabs and line endings when the ini is read, which also covers the \r of files saved with Windows line endings. Spaces inside a value are kept, and lines with an empty key are ignored. Verified with a new unit test that loads an ini with padded keys and values. Refs #1113 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -128,11 +128,19 @@ void dConfig::SetDatabaseSync(std::function<void(dConfig&)> sync) {
|
|||||||
void dConfig::ProcessLine(const std::string& line, const std::string& file, const std::string& description) {
|
void dConfig::ProcessLine(const std::string& line, const std::string& file, const std::string& description) {
|
||||||
auto splitLoc = line.find('=');
|
auto splitLoc = line.find('=');
|
||||||
if (splitLoc == std::string::npos) return;
|
if (splitLoc == std::string::npos) return;
|
||||||
auto key = line.substr(0, splitLoc);
|
// Stray spaces around keys and values (for example "client_location = ../client ") are a
|
||||||
auto value = line.substr(splitLoc + 1);
|
// common setup mistake that otherwise surfaces as an unrelated error much later, so drop them.
|
||||||
|
// This also removes the \r left at the end of lines of a file saved with Windows line endings.
|
||||||
//Make sure that on Linux, we remove special characters:
|
const auto trim = [](std::string_view str) {
|
||||||
if (!value.empty() && value.at(value.size() - 1) == '\r') value.erase(value.size() - 1);
|
constexpr std::string_view whitespace = " \t\r\n";
|
||||||
|
const auto start = str.find_first_not_of(whitespace);
|
||||||
|
if (start == std::string_view::npos) return std::string{};
|
||||||
|
const auto end = str.find_last_not_of(whitespace);
|
||||||
|
return std::string{ str.substr(start, end - start + 1) };
|
||||||
|
};
|
||||||
|
const auto key = trim(std::string_view(line).substr(0, splitLoc));
|
||||||
|
const auto value = trim(std::string_view(line).substr(splitLoc + 1));
|
||||||
|
if (key.empty()) return;
|
||||||
|
|
||||||
if (this->m_ConfigValues.find(key) != this->m_ConfigValues.end()) return;
|
if (this->m_ConfigValues.find(key) != this->m_ConfigValues.end()) return;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
#include "ConfigSync.h"
|
#include "ConfigSync.h"
|
||||||
|
#include "BinaryPathFinder.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void SetEnv(const char* name, const char* value) {
|
void SetEnv(const char* name, const char* value) {
|
||||||
@@ -111,3 +115,24 @@ TEST(ConfigLayerTests, OwnedValuesComeFromTheOwner) {
|
|||||||
EXPECT_EQ(config.GetValue("permission_accounts_ban"), "6");
|
EXPECT_EQ(config.GetValue("permission_accounts_ban"), "6");
|
||||||
EXPECT_EQ(config.GetValue("permission_players_view"), "2");
|
EXPECT_EQ(config.GetValue("permission_players_view"), "2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ConfigLayerTests, WhitespaceAroundKeysAndValuesIsIgnored) {
|
||||||
|
const auto path = BinaryPathFinder::GetBinaryDir() / "whitespace_test_config.ini";
|
||||||
|
{
|
||||||
|
std::ofstream out(path, std::ios::binary);
|
||||||
|
out << "zz_plain=value\n";
|
||||||
|
out << "zz_spaced = spaced value \r\n";
|
||||||
|
out << "\tzz_tabbed\t=\tx\t\n";
|
||||||
|
out << " = no key\n";
|
||||||
|
out << "zz_empty= \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dConfig config("whitespace_test_config.ini");
|
||||||
|
EXPECT_EQ(config.GetValue("zz_plain"), "value");
|
||||||
|
EXPECT_EQ(config.GetValue("zz_spaced"), "spaced value"); // inner spaces are kept
|
||||||
|
EXPECT_EQ(config.GetValue("zz_tabbed"), "x");
|
||||||
|
EXPECT_EQ(config.GetValue("zz_empty"), "");
|
||||||
|
EXPECT_EQ(config.GetValue(""), "");
|
||||||
|
|
||||||
|
std::filesystem::remove(path);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user