From 70bc943c17d5af510533e316f6526b318dd514c6 Mon Sep 17 00:00:00 2001 From: Qstick Date: Tue, 10 Jan 2023 21:45:43 -0600 Subject: [PATCH] Fixed: Correctly combine HttpUri paths with dot segment --- .../Http/HttpUriFixture.cs | 20 ++++++++++++ src/NzbDrone.Common/Http/HttpUri.cs | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs b/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs index f47c59881..3ffb150d9 100644 --- a/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpUriFixture.cs @@ -52,6 +52,26 @@ namespace NzbDrone.Common.Test.Http newUri.FullUri.Should().Be(expected); } + [TestCase("", "./relative", "relative")] + [TestCase("/", "./relative", "/relative")] + [TestCase("/base", "./relative", "/relative")] + [TestCase("/base/sub", "./relative", "/base/relative")] + [TestCase("/base/sub/", "./relative", "/base/sub/relative")] + [TestCase("base/sub", "./relative", "base/relative")] + [TestCase("base/sub/", "./relative", "base/sub/relative")] + [TestCase("", "../relative", "relative")] + [TestCase("/", "../relative", "/relative")] + [TestCase("/base", "../relative", "/relative")] + [TestCase("/base/sub", "../relative", "/base/relative")] + [TestCase("/base/sub/", "../relative", "/base/sub/relative")] + [TestCase("base/sub", "../relative", "base/relative")] + [TestCase("base/sub/", "../relative", "base/sub/relative")] + public void should_combine_uri_with_dot_segment(string basePath, string relativePath, string expected) + { + var newUri = new HttpUri(basePath) + new HttpUri(relativePath); + newUri.FullUri.Should().Be(expected); + } + [TestCase("", "", "")] [TestCase("/", "", "/")] [TestCase("base", "", "base")] diff --git a/src/NzbDrone.Common/Http/HttpUri.cs b/src/NzbDrone.Common/Http/HttpUri.cs index f90e564f5..1a8332f74 100644 --- a/src/NzbDrone.Common/Http/HttpUri.cs +++ b/src/NzbDrone.Common/Http/HttpUri.cs @@ -164,6 +164,37 @@ namespace NzbDrone.Common.Http return relativePath; } + if (relativePath.StartsWith("./")) + { + relativePath = relativePath.TrimStart('.').TrimStart('/'); + + var lastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, lastIndex) + "/"; + } + } + + if (relativePath.StartsWith("../")) + { + relativePath = relativePath.TrimStart('.').TrimStart('/'); + + var lastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, lastIndex) + "/"; + } + + var secondLastIndex = basePath.LastIndexOf("/"); + + if (lastIndex > 0) + { + basePath = basePath.Substring(0, secondLastIndex) + "/"; + } + } + var baseSlashIndex = basePath.LastIndexOf('/'); if (baseSlashIndex >= 0)