diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a419750c..11bd3eaae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [SIL.Chorus] Fix collection-modified exception when UsbDrives property is read while background scan thread updates the list - [SIL.Chorus.LibChorus] Fix null-key insertion when XML record identifier attribute is absent in XmlMergeService - [SIL.Chorus.LibChorus] Fix crash in password encryption/decryption on non-Windows platforms and on Windows data-protection failure +- [SIL.Chorus.LibChorus] Fix IndexOutOfRangeException parsing ChorusHub query parameters without '=', and preserve values containing '=' ## [5.1.0] - 2023-03-07 diff --git a/src/ChorusHubTests/ChorusHubTests.cs b/src/ChorusHubTests/ChorusHubTests.cs index 8e4bee822..7f3812652 100644 --- a/src/ChorusHubTests/ChorusHubTests.cs +++ b/src/ChorusHubTests/ChorusHubTests.cs @@ -240,4 +240,39 @@ public void GetRepostoryNames_TwoItemsInHubFolder_GetNoneForProjectFilter() } } } + + [TestFixture] + public class ChorusHubServerInfoParseTests + { + [Test] + public void Parse_SegmentWithoutEquals_DoesNotThrow() + { + const string input = "ChorusHubInfo?version=3&address=192.168.1.1&port=5912&hostname=mypc&flag"; + Assert.DoesNotThrow(() => ChorusHubServerInfo.Parse(input)); + } + + [Test] + public void Parse_SegmentWithoutEquals_OtherValuesStillParsed() + { + const string input = "ChorusHubInfo?version=3&address=192.168.1.1&port=5912&hostname=mypc&flag"; + var info = ChorusHubServerInfo.Parse(input); + Assert.That(info.HostName, Is.EqualTo("mypc")); + } + + [Test] + public void Parse_ValueContainsEquals_FullValuePreserved() + { + const string input = "ChorusHubInfo?version=3&address=192.168.1.1&port=5912&hostname=my=pc"; + var info = ChorusHubServerInfo.Parse(input); + Assert.That(info.HostName, Is.EqualTo("my=pc")); + } + + [Test] + public void Parse_SegmentWithoutEquals_ParsedWithEmptyValue() + { + const string input = "ChorusHubInfo?version=3&address=192.168.1.1&port=5912&hostname"; + var info = ChorusHubServerInfo.Parse(input); + Assert.That(info.HostName, Is.EqualTo("")); + } + } } diff --git a/src/LibChorus/ChorusHub/ChorusHubServerInfo.cs b/src/LibChorus/ChorusHub/ChorusHubServerInfo.cs index 8bd6f174c..5d8b7b748 100644 --- a/src/LibChorus/ChorusHub/ChorusHubServerInfo.cs +++ b/src/LibChorus/ChorusHub/ChorusHubServerInfo.cs @@ -53,15 +53,11 @@ public static ChorusHubServerInfo Parse(string parameters) private static string GetValue(string parameters, string name) { var queryParameters = new NameValueCollection(); - var querySegments = parameters.Split('&'); - foreach (var segment in querySegments) + foreach (var segment in parameters.Split('&')) { - var parts = segment.Split('='); - if (parts.Length < 1) - continue; - + var parts = segment.Split(new[] { '=' }, 2); var key = parts[0].Trim(new[] { '?', ' ' }); - var val = parts[1].Trim(); + var val = parts.Length < 2 ? "" : parts[1].Trim(); queryParameters.Add(key, val); }