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); + } + } +}