Skip to content

Commit

Permalink
fixes #16 - when key value contains itself a valid key and a value
Browse files Browse the repository at this point in the history
  • Loading branch information
salaros committed Mar 15, 2021
1 parent 47353cf commit ee60daf
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Operating system (build VM template)
os: Windows Server 2016
os: Windows Server 2019

# If the build configuration does not specify build worker image
# then Visual Studio 2015 image is used.
Expand Down Expand Up @@ -93,7 +93,7 @@ deploy:
-
provider: NuGet
api_key:
secure: i6oWn60J7ZOM4UuYcvxbuk9OAEp6or+Wq7izyJDPNlcLIhG2UKsxz7G/8erhdY3M
secure: fLRrY6iKFQhPFD5fHraib6Ot+0x3eKiVWoBCiKT5zPRCqxWxLAycIO8lJWg3o43r
artifact: NuGet_Files
server: # remove to push to NuGet.org
skip_symbols: false
Expand Down
27 changes: 24 additions & 3 deletions src/ConfigParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,10 @@ private void Read(string configContent)
break;

case var _ when Settings.KeyMatcher.IsMatch(lineRaw):
ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber);
if (!Settings.MultiLineValues.HasFlag(MultiLineValues.NotAllowed) && IsKeyLikeArrayValue(currentLine?.Content, lineRaw))
ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber, append: true, forceIncludeKey: true);
else
ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber);
break;

// Multi-line + allow value-less option on
Expand Down Expand Up @@ -697,6 +700,21 @@ private void Read(string configContent)
sections.Add(currentSection.SectionName, currentSection);
}

private bool IsKeyLikeArrayValue(string currentLine, string lineRaw)
{
if (string.IsNullOrWhiteSpace(currentLine) || string.IsNullOrWhiteSpace(lineRaw))
return false;

var lastLine = currentLine?.Split(new string[] { Settings.NewLine }, StringSplitOptions.None)?.LastOrDefault();
var prevLineMatch = Settings.ArrayStartMatcher.Match(lastLine);
var curLineMatch = Settings.ArrayStartMatcher.Match(lineRaw);

if (!prevLineMatch.Success || !curLineMatch.Success)
return false;

return prevLineMatch.Groups[0].Value.Length == curLineMatch.Groups[0].Value.Length;
}

/// <summary>
/// Reads the valueless key.
/// </summary>
Expand Down Expand Up @@ -726,9 +744,11 @@ private void AppendValueToKey(ref ConfigSection currentSection, ref ConfigLine c
{
if (MultiLineValues.NotAllowed == Settings.MultiLineValues ||
Settings.MultiLineValues.HasFlag(MultiLineValues.NotAllowed))
{
throw new ConfigParserException(
"Multi-line values are explicitly disallowed by parser settings. Please consider changing them.",
lineNumber);
}

ReadKeyAndValue(ref currentSection, ref currentLine, lineRaw, lineNumber, true);
}
Expand All @@ -745,7 +765,7 @@ private void AppendValueToKey(ref ConfigSection currentSection, ref ConfigLine c
/// or</exception>
/// <exception cref="NotImplementedException"></exception>
private void ReadKeyAndValue(ref ConfigSection currentSection, ref ConfigLine currentLine, string lineRaw,
int lineNumber, bool append = false)
int lineNumber, bool append = false, bool forceIncludeKey = false)
{
if (null != currentLine && !append)
BackupCurrentLine(ref currentSection, ref currentLine, lineNumber);
Expand All @@ -758,7 +778,8 @@ private void ReadKeyAndValue(ref ConfigSection currentSection, ref ConfigLine cu
var separator = (string.IsNullOrWhiteSpace(keyMatch.Groups["separator"]?.Value))
? Settings.KeyValueSeparator
: keyMatch.Groups["separator"]?.Value;
if (keyMatch.Success && keyMatch.Captures.Count > 0)

if (!forceIncludeKey && keyMatch.Success && keyMatch.Captures.Count > 0)
lineRaw = lineRaw.Substring(keyMatch.Captures[0].Value.Length);

var valueMatch = Settings.ValueMatcher.Match(lineRaw);
Expand Down
8 changes: 4 additions & 4 deletions src/ConfigParser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
<Copyright>Copyright 2015 (c) Salaros</Copyright>
<Title>ConfigParser</Title>
<Description>A slim, cross-platform, fully managed C# library for reading/writing .ini, .conf, .cfg etc configuration files.</Description>
<Version>1.0.0</Version>
<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
<Version>0.3.7</Version>
<AssemblyVersion>0.3.7</AssemblyVersion>
<FileVersion>0.3.7</FileVersion>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseUrl>https://raw.githubusercontent.com/salaros/config-parser/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/salaros/config-parser</PackageProjectUrl>
Expand Down Expand Up @@ -67,5 +67,5 @@
<Delete Files="@(NuGetFilesBin)" />
<Delete Files="@(NuGetFilesProject)" />
</Target>

</Project>
7 changes: 6 additions & 1 deletion src/ConfigParserSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Salaros.Configuration
{
public class ConfigParserSettings
{
protected Regex keyMatcher, commentMatcher, valueMatcher;
protected Regex keyMatcher, commentMatcher, valueMatcher, arrayStartMatcher;

/// <summary>
/// Initializes the <see cref="ConfigParserSettings"/> class.
Expand Down Expand Up @@ -84,6 +84,11 @@ static ConfigParserSettings()
/// </value>
internal static Regex SectionMatcher { get; set; }

/// <summary>Gets the array value line matcher (matches the whitespaces at the beggining of each array value).</summary>
/// <value>The array start matcher.</value>
internal Regex ArrayStartMatcher => arrayStartMatcher ?? (arrayStartMatcher =
new Regex(@"^(\s{1,})", RegexOptions.Compiled));

/// <summary>
/// Gets the comment matcher.
/// </summary>
Expand Down
24 changes: 24 additions & 0 deletions tests/ConfigParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,29 @@ public void FileCanBeSavedToNewPath()

Assert.True(File.Exists(configFilePathTmpNew));
}

[Fact]
public void ArrayIsReadCorrectly()
{
// Set up
var settings = new ConfigParserSettings { MultiLineValues = MultiLineValues.Simple | MultiLineValues.QuoteDelimitedValues };
var configFile = new ConfigParser(
@"[Advanced]
Select =
select * from
from table
where ID = '5'
",
settings);

// Act
var arrayValues = configFile.GetArrayValue("Advanced", "Select");

// Assert
Assert.Equal(3, arrayValues?.Length ?? 0);
Assert.Equal("select * from", arrayValues[0]);
Assert.Equal("from table", arrayValues[1]);
Assert.Equal("where ID = '5'", arrayValues[2]);
}
}
}

0 comments on commit ee60daf

Please sign in to comment.