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