From a45ce610df047eb54e89cb9ef26f7364ef90cc52 Mon Sep 17 00:00:00 2001 From: Jojo-1000 <33495614+Jojo-1000@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:53:10 +0100 Subject: [PATCH] Fix URI parsing for IPv6 addresses and add tests. Closes #5057 --- Duplicati/Library/Utility/Uri.cs | 2 +- Duplicati/UnitTest/UriUtilityTests.cs | 57 +++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Duplicati/Library/Utility/Uri.cs b/Duplicati/Library/Utility/Uri.cs index 19be6be5b..71dbe8671 100644 --- a/Duplicati/Library/Utility/Uri.cs +++ b/Duplicati/Library/Utility/Uri.cs @@ -34,7 +34,7 @@ namespace Duplicati.Library.Utility /// /// A very lax version of a URL parser /// - private static readonly System.Text.RegularExpressions.Regex URL_PARSER = new System.Text.RegularExpressions.Regex(@"(?[^:]+)://(((?[^\:\?/]+)(\:(?[^@\:\?/]*))?\@))?((?[^/\?\:]+)(\:(?\d+))?)?((?[^\?]*))?(\?(?.+))?"); + private static readonly System.Text.RegularExpressions.Regex URL_PARSER = new System.Text.RegularExpressions.Regex(@"(?[^:]+)://(((?[^\:\?/]+)(\:(?[^@\:\?/]*))?\@))?((?(?:[^\[/\?\:][^/\?\:]*)|(?:\[[^\]]+\]))(\:(?\d+))?)?((?[^\?]*))?(\?(?.+))?"); /// /// The URL scheme, e.g. http diff --git a/Duplicati/UnitTest/UriUtilityTests.cs b/Duplicati/UnitTest/UriUtilityTests.cs index 8997ec934..df8a330fe 100644 --- a/Duplicati/UnitTest/UriUtilityTests.cs +++ b/Duplicati/UnitTest/UriUtilityTests.cs @@ -17,11 +17,11 @@ using NUnit.Framework; using System.Collections.Specialized; - -namespace Duplicati.UnitTest -{ - public class UriUtilityTests - { + +namespace Duplicati.UnitTest +{ + public class UriUtilityTests + { [Test] [Category("UriUtility")] public static void TestBuildUriQuery() @@ -65,5 +65,48 @@ namespace Duplicati.UnitTest Assert.AreEqual("/a", Library.Utility.UrlPath.Create(path1).Append(null).ToString()); Assert.AreEqual("/b/", Library.Utility.UrlPath.Create(string.Empty).Append(path2).ToString()); } - } -} + + [Test] + [Category("UriUtility")] + public static void TestUriParse( + [Values("[1:2:3::4]", "127.0.0.1", "hostname")] string host, + [Values("", "user@", "user:pw@")] string user, + [Values("", ":80")] string port, + [Values("", "/path")] string path, + [Values("", "?query")] string query) + { + string uriStr = $"http://{user}{host}{port}{path}{query}"; + + var uri = new Library.Utility.Uri(uriStr); + Assert.AreEqual("http", uri.Scheme); + Assert.AreEqual(host, uri.Host); + if (port.Length != 0) + { + Assert.AreEqual(80, uri.Port); + } + else + { + Assert.AreEqual(-1, uri.Port); + } + Assert.AreEqual(path.TrimStart('/'), uri.Path); + Assert.AreEqual(query.Length == 0 ? null : query.TrimStart('?'), uri.Query); + if (user.Length == 0) + { + Assert.IsNull(uri.Username); + Assert.IsNull(uri.Password); + } + else + { + Assert.AreEqual("user", uri.Username); + if (user.Contains(":")) + { + Assert.AreEqual("pw", uri.Password); + } + else + { + Assert.IsNull(uri.Password); + } + } + } + } +}