From 356f270b128a826d7f1f0e0b764b6890be99f9e6 Mon Sep 17 00:00:00 2001 From: Kenneth Hsu Date: Tue, 10 Aug 2021 10:30:54 -0700 Subject: Fix handling of FTP paths that contain escaped characters. This fixes #4587. --- .../Backend/AlternativeFTP/AlternativeFTPBackend.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'Duplicati') diff --git a/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs b/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs index 23d3a3f6c..65b51f5c5 100644 --- a/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs +++ b/Duplicati/Library/Backend/AlternativeFTP/AlternativeFTPBackend.cs @@ -30,8 +30,8 @@ using System.Security.Authentication; using System.Threading; using System.Threading.Tasks; using CoreUtility = Duplicati.Library.Utility.Utility; -using Uri = System.Uri; - +using Uri = System.Uri; + namespace Duplicati.Library.Backend.AlternativeFTP { // ReSharper disable once RedundantExtendsListEntry @@ -221,7 +221,7 @@ namespace Duplicati.Library.Backend.AlternativeFTP // Get the remote path var url = new Uri(this._url); - remotePath = "/" + (url.AbsolutePath.EndsWith("/", StringComparison.Ordinal) ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath); + remotePath = "/" + this.GetUnescapedAbsolutePath(url); if (!string.IsNullOrEmpty(filename)) { @@ -513,7 +513,7 @@ namespace Duplicati.Library.Backend.AlternativeFTP var url = new Uri(_url); // Get the remote path - var remotePath = url.AbsolutePath.EndsWith("/", StringComparison.Ordinal) ? url.AbsolutePath.Substring(0, url.AbsolutePath.Length - 1) : url.AbsolutePath; + var remotePath = this.GetUnescapedAbsolutePath(url); // Try to create the directory client.CreateDirectory(remotePath, true); @@ -555,12 +555,18 @@ namespace Duplicati.Library.Backend.AlternativeFTP // Change working directory to the remote path // Do this every time to prevent issues when FtpClient silently reconnects after failure. - var remotePath = uri.AbsolutePath.EndsWith("/", StringComparison.Ordinal) ? uri.AbsolutePath.Substring(0, uri.AbsolutePath.Length - 1) : uri.AbsolutePath; + var remotePath = this.GetUnescapedAbsolutePath(uri); this.Client.SetWorkingDirectory(remotePath); return this.Client; } + private string GetUnescapedAbsolutePath(Uri uri) + { + string absolutePath = Uri.UnescapeDataString(uri.AbsolutePath); + return absolutePath.EndsWith("/", StringComparison.Ordinal) ? absolutePath.Substring(0, absolutePath.Length - 1) : absolutePath; + } + private void HandleValidateCertificate(FtpClient control, FtpSslValidationEventArgs e) { if (e.PolicyErrors == SslPolicyErrors.None || _accepAllCertificates) -- cgit v1.2.3