From b89746c2eeea16f4d7fbc7bb88a2a03c8f77d880 Mon Sep 17 00:00:00 2001 From: "FIFER Mods (Lewis)" Date: Sat, 6 Jun 2026 23:46:46 -0400 Subject: [PATCH] Fix sectionless files dropping all settings A config with top-level settings but no [section] header parsed to an empty Configuration. The default section holding those settings is only added when a [section] header is read, so with no header it was never added. Add it after the parse loop instead. --- Src/ConfigurationReader.cs | 8 ++++++++ Tests/SectionlessConfigTest.cs | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Tests/SectionlessConfigTest.cs diff --git a/Src/ConfigurationReader.cs b/Src/ConfigurationReader.cs index af25692..40d88c9 100644 --- a/Src/ConfigurationReader.cs +++ b/Src/ConfigurationReader.cs @@ -107,6 +107,14 @@ private static void Parse(StringReader reader, Configuration config) currentSection.Add(setting); } } + + // If the source contained settings but never opened a named section, the + // default section was never added above (that only happens when the first + // '[' is encountered). Commit it here so its settings aren't silently lost. + if (currentSection.Name == Section.DefaultSectionName && currentSection.SettingCount > 0) + { + config.Add(currentSection); + } } private static string? ParseComment(string line, out int commentCharIndex) diff --git a/Tests/SectionlessConfigTest.cs b/Tests/SectionlessConfigTest.cs new file mode 100644 index 0000000..1fe7d11 --- /dev/null +++ b/Tests/SectionlessConfigTest.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2013-2026 Cem Dervis, MIT License. +// https://sharpconfig.org + +using NUnit.Framework; +using Assert = NUnit.Framework.Legacy.ClassicAssert; +using SharpConfig; + +namespace Tests +{ + [TestFixture] + public sealed class SectionlessConfigTest + { + [Test] + public void SectionlessFileKeepsSettings() + { + var cfg = Configuration.LoadFromString("Setting1 = Value1\nSetting2 = Value2"); + + Assert.AreEqual(2, cfg.DefaultSection.SettingCount); + Assert.AreEqual("Value1", cfg.DefaultSection["Setting1"].StringValue); + Assert.AreEqual("Value2", cfg.DefaultSection["Setting2"].StringValue); + + // Round-trips without gaining a section header. + var saved = cfg.SaveToString(); + Assert.IsFalse(saved.Contains('[')); + Assert.AreEqual(2, Configuration.LoadFromString(saved).DefaultSection.SettingCount); + } + } +}