From 097b06959ccb1c2380d97ff353c7d277ed177bd1 Mon Sep 17 00:00:00 2001 From: Gabriela Trutan Date: Wed, 4 Sep 2024 13:15:58 +0200 Subject: [PATCH] SLVS-1436 Implement review feedback: - remove check if the filename contains reserved char for performance reason - remove ? char from reserved list, because it is not supported in file names in windows and it also increases performance - use string builder to improve performance - add more unit tests --- .../Common/Models/FileUriTests.cs | 41 +++++++++++++++++++ src/SLCore/Common/Models/FileUri.cs | 15 ++++--- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/SLCore.UnitTests/Common/Models/FileUriTests.cs b/src/SLCore.UnitTests/Common/Models/FileUriTests.cs index bde788b15..1c410da28 100644 --- a/src/SLCore.UnitTests/Common/Models/FileUriTests.cs +++ b/src/SLCore.UnitTests/Common/Models/FileUriTests.cs @@ -134,6 +134,47 @@ public void LocalPath_ReturnsCorrectPath() new FileUri(filePath).LocalPath.Should().Be(filePath); } + [TestMethod] + [DataRow("[", "%5B")] + [DataRow("]", "%5D")] + [DataRow("#", "%2523")] + [DataRow("@", "%40")] + [DataRow(" ", "%20")] + [DataRow("`", "%60")] + public void LocalPath_UnescapesEncodesCharacters(string reservedChar, string expectedEncoding) + { + var expectedFilePath = @$"C:\filewithRfc3986ReservedChar{reservedChar}.cs"; + var encodedFilePath = @$"file:///C:/filewithRfc3986ReservedChar{expectedEncoding}.cs"; + + new FileUri(encodedFilePath).LocalPath.Should().Be(expectedFilePath); + } + + [TestMethod] + [DataRow("[")] + [DataRow("]")] + [DataRow("@")] + [DataRow(" ")] + [DataRow("`")] + public void LocalPath_PathDoesNotHaveEncodedChars_ReturnsCorrectLocalPath(string reservedChar) + { + var notEncodedFilePath = @$"file:///C:/filewithRfc3986ReservedChar{reservedChar}.cs"; + var expectedFilePath = @$"C:\filewithRfc3986ReservedChar{reservedChar}.cs"; + + new FileUri(notEncodedFilePath).LocalPath.Should().Be(expectedFilePath); + } + + /// + /// The # character as the beginning of a fragment, so will return the path without the fragment. + /// + [TestMethod] + public void LocalPath_PathWithHashCharacter_ReturnsLocalPathWithoutHash() + { + var notEncodedFilePath = @$"file:///C:/filewithRfc3986ReservedChar#.cs"; + var expectedFilePath = @$"C:\filewithRfc3986ReservedChar"; + + new FileUri(notEncodedFilePath).LocalPath.Should().Be(expectedFilePath); + } + [TestMethod] public void SerializeDeserializeToEqualObject() { diff --git a/src/SLCore/Common/Models/FileUri.cs b/src/SLCore/Common/Models/FileUri.cs index 775de8ab4..ede896602 100644 --- a/src/SLCore/Common/Models/FileUri.cs +++ b/src/SLCore/Common/Models/FileUri.cs @@ -20,8 +20,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; +using System.Text; using SonarLint.VisualStudio.SLCore.Protocol; namespace SonarLint.VisualStudio.SLCore.Common.Models; @@ -30,7 +29,7 @@ namespace SonarLint.VisualStudio.SLCore.Common.Models; public sealed class FileUri { private readonly Uri uri; - private static readonly char[] Rfc3986ReservedCharsToEncoding = ['?', '#', '[', ']', '@']; + private static readonly char[] Rfc3986ReservedCharsToEncode = ['#', '[', ']', '@']; public FileUri(string uriString) { @@ -56,11 +55,11 @@ public override string ToString() /// private static string EscapeRfc3986ReservedCharacters(string stringToEscape) { - var charsToEscape = Rfc3986ReservedCharsToEncoding.Where(stringToEscape.Contains).ToList(); - - return !charsToEscape.Any() - ? stringToEscape - : charsToEscape.Aggregate(stringToEscape, (current, charToEscape) => current.Replace(charToEscape.ToString(), Uri.HexEscape(charToEscape))); + var stringBuilderToEscape = new StringBuilder(stringToEscape); + + return Rfc3986ReservedCharsToEncode.Aggregate(stringBuilderToEscape, + (current, charToEscape) => current.Replace(charToEscape.ToString(), Uri.HexEscape(charToEscape))) + .ToString(); } [ExcludeFromCodeCoverage]