From 4ec246cfb68770c9de5a68e5b3ac7bed77a6f276 Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 25 Mar 2024 19:06:19 +0100 Subject: [PATCH 1/8] give longer --- starsky/starsky.foundation.platform/Helpers/PathHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs index 018b3cfeb7..3917bdd85d 100644 --- a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs +++ b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs @@ -17,7 +17,7 @@ public static partial class PathHelper [GeneratedRegex( "[^/]+(?=(?:\\.[^.]+)?$)", RegexOptions.CultureInvariant, - matchTimeoutMilliseconds: 300)] + matchTimeoutMilliseconds: 1000)] private static partial Regex GetFileNameRegex(); /// From bf60c3192cfe91b6fd73f0bacb5bdc470a3667c2 Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 25 Mar 2024 19:11:58 +0100 Subject: [PATCH 2/8] keep a changelog --- history.md | 1 + 1 file changed, 1 insertion(+) diff --git a/history.md b/history.md index bb2df853f6..aa0c01113e 100644 --- a/history.md +++ b/history.md @@ -45,6 +45,7 @@ Semantic Versioning 2.0.0 is from version 0.1.6+ - [x] (Changed) _Front-end_ Make prev / next more contrast (PR #1511) - [x] (Fixed) _Docs_ Demo site is not working (PR #1486) +- [x] (Fixed) _Back-end_ GetFileNameRegex give longer to avoid timeouts (PR #1515) ## version 0.6.0 - 2024-03-15 {#v0.6.0} From c28518c0e0f7759ba230fc11a930390e71cebd23 Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 25 Mar 2024 19:43:14 +0100 Subject: [PATCH 3/8] more input --- .../starsky.foundation.platform/Helpers/PathHelperTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs index 11f62d3c5d..33ab9eaed8 100644 --- a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs +++ b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs @@ -28,7 +28,7 @@ public void GetFileName_ReturnsValidFileName() [TestMethod] [ExpectedException(typeof(RegexMatchTimeoutException))] - public async Task GetFileName_ReturnsFileName_WithMaliciousInput_UnixOnly() + public async Task GetFileName_ReturnsFileName_WithMaliciousInput() { // Act and Assert var test = await @@ -39,7 +39,7 @@ public async Task GetFileName_ReturnsFileName_WithMaliciousInput_UnixOnly() new MemoryStream(CreateAnImageA6600.Bytes.ToArray())); var result = string.Empty; - for ( var i = 0; i < 200; i++ ) + for ( var i = 0; i < 2000; i++ ) { result += test + test2 + test + test; } From 4df04d5c0ababcbe6b32bf59d2958592a6cf3b81 Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 25 Mar 2024 19:45:46 +0100 Subject: [PATCH 4/8] try this --- .../starsky.foundation.platform/Helpers/PathHelperTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs index 33ab9eaed8..4567cb74d4 100644 --- a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs +++ b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs @@ -39,7 +39,7 @@ public async Task GetFileName_ReturnsFileName_WithMaliciousInput() new MemoryStream(CreateAnImageA6600.Bytes.ToArray())); var result = string.Empty; - for ( var i = 0; i < 2000; i++ ) + for ( var i = 0; i < 1000; i++ ) { result += test + test2 + test + test; } From aa1e9dabefbbee392d19501a6954885291edc30a Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 25 Mar 2024 20:10:20 +0100 Subject: [PATCH 5/8] idea --- .../Helpers/PathHelper.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs index 3917bdd85d..ca4f14a773 100644 --- a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs +++ b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs @@ -35,6 +35,78 @@ public static string GetFileName(string? filePath) return GetFileNameRegex().Match(filePath).Value; } + private static string? GetFileNameHelper(string input) + { + // Initialize variables to store the result + string result = ""; + bool isValid = true; + + // Define variables to keep track of the current position and length of the match + int startPos = 0; + int matchLength = 0; + + // Iterate over the characters in the input string + for (int i = 0; i < input.Length; i++) + { + // If the current character is '/', it means the end of a potential match + if (input[i] == '/') + { + // Extract the potential match substring + string potentialMatch = input.Substring(startPos, matchLength); + + // Check if the potential match matches the pattern [^/]+(?=(?:\.[^.]+)?$) + if (!potentialMatch.Contains("/") && (potentialMatch.Contains(".") || potentialMatch.EndsWith("."))) + { + // Add the potential match to the result + result += potentialMatch + "/"; + + // Update the start position for the next potential match + startPos = i + 1; + matchLength = 0; + } + else + { + // If the potential match does not match the pattern, set isValid to false and break the loop + isValid = false; + break; + } + } + else + { + // Increment the length of the potential match + matchLength++; + } + } + + // Handle the last potential match after the loop + if (matchLength > 0) + { + string lastPotentialMatch = input.Substring(startPos, matchLength); + if (!lastPotentialMatch.Contains("/") && (lastPotentialMatch.Contains(".") || lastPotentialMatch.EndsWith("."))) + { + result += lastPotentialMatch; + } + else + { + isValid = false; + } + } + + // If isValid is true and result is not empty, remove the trailing '/' + if (isValid && result.Length > 0) + { + result = result.TrimEnd('/'); + } + else + { + // If the input string does not match the pattern, set result to null + result = null; + } + + // Output the result + return result; + } + /// /// Removes the latest backslash. Path.DirectorySeparatorChar /// From a9256772ba4574ade34646eaf1215c43cb289691 Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 8 Apr 2024 11:53:10 +0200 Subject: [PATCH 6/8] Fix regex issue --- .../Helpers/PathHelper.cs | 112 ++++----------- .../Helpers/PathHelperTest.cs | 134 ++++++++++++------ 2 files changed, 116 insertions(+), 130 deletions(-) diff --git a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs index ca4f14a773..4724a78b53 100644 --- a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs +++ b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs @@ -1,25 +1,13 @@ +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; -using System.Text.RegularExpressions; namespace starsky.foundation.platform.Helpers { - public static partial class PathHelper + public static class PathHelper { - /// - /// Regex to match a filename in a path - /// unescaped: - /// [^/]+(?=(?:\.[^.]+)?$) - /// pre compiled regex Regex.Match - /// - /// Regex object - [GeneratedRegex( - "[^/]+(?=(?:\\.[^.]+)?$)", - RegexOptions.CultureInvariant, - matchTimeoutMilliseconds: 1000)] - private static partial Regex GetFileNameRegex(); - /// /// Return value (works for POSIX/Windows paths) /// @@ -32,81 +20,33 @@ public static string GetFileName(string? filePath) return string.Empty; } - return GetFileNameRegex().Match(filePath).Value; + if ( filePath.Length >= 4095 ) + { + // why? https://serverfault.com/questions/9546/filename-length-limits-on-linux + throw new ArgumentException("[PathHelper] FilePath over Unix limits", nameof(filePath)); + } + + var fileName = GetFileNameUnix(filePath.AsSpan()); + return fileName.ToString(); } - private static string? GetFileNameHelper(string input) + [SuppressMessage("Style", "IDE0057:Use range operator")] + [SuppressMessage("ReSharper", "ReplaceSliceWithRangeIndexer")] + private static ReadOnlySpan GetFileNameUnix(ReadOnlySpan path) { - // Initialize variables to store the result - string result = ""; - bool isValid = true; - - // Define variables to keep track of the current position and length of the match - int startPos = 0; - int matchLength = 0; - - // Iterate over the characters in the input string - for (int i = 0; i < input.Length; i++) - { - // If the current character is '/', it means the end of a potential match - if (input[i] == '/') - { - // Extract the potential match substring - string potentialMatch = input.Substring(startPos, matchLength); - - // Check if the potential match matches the pattern [^/]+(?=(?:\.[^.]+)?$) - if (!potentialMatch.Contains("/") && (potentialMatch.Contains(".") || potentialMatch.EndsWith("."))) - { - // Add the potential match to the result - result += potentialMatch + "/"; - - // Update the start position for the next potential match - startPos = i + 1; - matchLength = 0; - } - else - { - // If the potential match does not match the pattern, set isValid to false and break the loop - isValid = false; - break; - } - } - else - { - // Increment the length of the potential match - matchLength++; - } - } - - // Handle the last potential match after the loop - if (matchLength > 0) - { - string lastPotentialMatch = input.Substring(startPos, matchLength); - if (!lastPotentialMatch.Contains("/") && (lastPotentialMatch.Contains(".") || lastPotentialMatch.EndsWith("."))) - { - result += lastPotentialMatch; - } - else - { - isValid = false; - } - } - - // If isValid is true and result is not empty, remove the trailing '/' - if (isValid && result.Length > 0) - { - result = result.TrimEnd('/'); - } - else - { - // If the input string does not match the pattern, set result to null - result = null; - } + var length = GetPathRootUnix(path).Length; + var num = path.LastIndexOf('/'); + return path.Slice(num < length ? length : num + 1); + } - // Output the result - return result; + private static ReadOnlySpan GetPathRootUnix(ReadOnlySpan path) + { + return !IsPathRootedUnix(path) ? [] : "/".AsSpan(); } + private static bool IsPathRootedUnix(ReadOnlySpan path) => + path.Length > 0 && path[0] == '/'; + /// /// Removes the latest backslash. Path.DirectorySeparatorChar /// @@ -124,7 +64,7 @@ public static string GetFileName(string? filePath) // remove latest backslash if ( basePath.Substring(basePath.Length - 1, 1) == - Path.DirectorySeparatorChar.ToString() ) + Path.DirectorySeparatorChar.ToString() ) { basePath = basePath.Substring(0, basePath.Length - 1); } @@ -166,7 +106,7 @@ public static string AddBackslash(string thumbnailTempFolder) if ( string.IsNullOrWhiteSpace(thumbnailTempFolder) ) return thumbnailTempFolder; if ( thumbnailTempFolder.Substring(thumbnailTempFolder.Length - 1, - 1) != Path.DirectorySeparatorChar.ToString() ) + 1) != Path.DirectorySeparatorChar.ToString() ) { thumbnailTempFolder += Path.DirectorySeparatorChar.ToString(); } diff --git a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs index 4567cb74d4..3bdf960786 100644 --- a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs +++ b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs @@ -1,50 +1,35 @@ +using System; using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using starsky.foundation.platform.Helpers; -using starsky.foundation.storage.Helpers; -using starskytest.FakeCreateAn; namespace starskytest.starsky.foundation.platform.Helpers; [TestClass] public class PathHelperTests { - [TestMethod] - public void GetFileName_ReturnsValidFileName() + [DataTestMethod] // [Theory] + [DataRow("path/to/file.txt", "file.txt")] + [DataRow("file.txt", "file.txt")] + [DataRow("/file.txt", "file.txt")] + [DataRow("/test/file.txt", "file.txt")] + [DataRow("/test/file/", "")] + [DataRow("/test/file", "file")] // no backslash + public void GetFileName_ReturnsValidFileName(string input, string expectedFileName) { - // Arrange - const string filePath = "path/to/file.txt"; - const string expectedFileName = "file.txt"; - // Act - var actualFileName = PathHelper.GetFileName(filePath); + var actualFileName = PathHelper.GetFileName(input); // Assert Assert.AreEqual(expectedFileName, actualFileName); } [TestMethod] - [ExpectedException(typeof(RegexMatchTimeoutException))] - public async Task GetFileName_ReturnsFileName_WithMaliciousInput() + [ExpectedException(typeof(ArgumentException))] + public void GetFileName_ReturnsFileName_WithMaliciousInput() { // Act and Assert - var test = await - StreamToStringHelper.StreamToStringAsync( - new MemoryStream(CreateAnImage.Bytes.ToArray())); - var test2 = await - StreamToStringHelper.StreamToStringAsync( - new MemoryStream(CreateAnImageA6600.Bytes.ToArray())); - - var result = string.Empty; - for ( var i = 0; i < 1000; i++ ) - { - result += test + test2 + test + test; - } - - PathHelper.GetFileName(result); + PathHelper.GetFileName(TestContentVeryLongString); } [TestMethod] @@ -104,11 +89,11 @@ public void RemoveLatestBackslash_ReturnsBasePath_WhenBasePathIsRoot() public void RemoveLatestSlash_RemovesLatestSlash_WhenSlashExists() { // Arrange - string basePath = "/path/to/directory/"; - string expectedPath = "/path/to/directory"; + const string basePath = "/path/to/directory/"; + const string expectedPath = "/path/to/directory"; // Act - string actualPath = PathHelper.RemoveLatestSlash(basePath); + var actualPath = PathHelper.RemoveLatestSlash(basePath); // Assert Assert.AreEqual(expectedPath, actualPath); @@ -118,10 +103,10 @@ public void RemoveLatestSlash_RemovesLatestSlash_WhenSlashExists() public void RemoveLatestSlash_DoesNotRemoveSlash_WhenSlashDoesNotExist() { // Arrange - string basePath = "/path/to/directory"; + const string basePath = "/path/to/directory"; // Act - string actualPath = PathHelper.RemoveLatestSlash(basePath); + var actualPath = PathHelper.RemoveLatestSlash(basePath); // Assert Assert.AreEqual(basePath, actualPath); @@ -131,7 +116,7 @@ public void RemoveLatestSlash_DoesNotRemoveSlash_WhenSlashDoesNotExist() public void RemoveLatestSlash_ReturnsEmptyString_WhenBasePathIsNull() { // Act - string actualPath = PathHelper.RemoveLatestSlash(null!); + var actualPath = PathHelper.RemoveLatestSlash(null!); // Assert Assert.AreEqual(string.Empty, actualPath); @@ -141,10 +126,10 @@ public void RemoveLatestSlash_ReturnsEmptyString_WhenBasePathIsNull() public void RemoveLatestSlash_ReturnsEmptyString_WhenBasePathIsEmpty() { // Arrange - string basePath = string.Empty; + var basePath = string.Empty; // Act - string actualPath = PathHelper.RemoveLatestSlash(basePath); + var actualPath = PathHelper.RemoveLatestSlash(basePath); // Assert Assert.AreEqual(string.Empty, actualPath); @@ -154,10 +139,10 @@ public void RemoveLatestSlash_ReturnsEmptyString_WhenBasePathIsEmpty() public void RemoveLatestSlash_ReturnsEmptyString_WhenBasePathIsRoot() { // Arrange - string basePath = "/"; + const string basePath = "/"; // Act - string actualPath = PathHelper.RemoveLatestSlash(basePath); + var actualPath = PathHelper.RemoveLatestSlash(basePath); // Assert Assert.AreEqual(string.Empty, actualPath); @@ -263,7 +248,7 @@ public void PrefixDbSlash_WhenCalledWithAlreadyPrefixedPath_ReturnsPathWithoutCh const string expected = "/test/subfolder/file.txt"; // Act - string result = PathHelper.PrefixDbSlash(subPath); + var result = PathHelper.PrefixDbSlash(subPath); // Assert Assert.AreEqual(expected, result); @@ -273,10 +258,10 @@ public void PrefixDbSlash_WhenCalledWithAlreadyPrefixedPath_ReturnsPathWithoutCh public void TestRemovePrefixDbSlash_WithLeadingSlash() { // Arrange - string subPath = "/path/to/file"; + const string subPath = "/path/to/file"; // Act - string result = PathHelper.RemovePrefixDbSlash(subPath); + var result = PathHelper.RemovePrefixDbSlash(subPath); // Assert Assert.AreEqual("path/to/file", result); @@ -286,10 +271,10 @@ public void TestRemovePrefixDbSlash_WithLeadingSlash() public void TestRemovePrefixDbSlash_WithoutLeadingSlash() { // Arrange - string subPath = "path/to/file"; + const string subPath = "path/to/file"; // Act - string result = PathHelper.RemovePrefixDbSlash(subPath); + var result = PathHelper.RemovePrefixDbSlash(subPath); // Assert Assert.AreEqual("path/to/file", result); @@ -302,7 +287,7 @@ public void TestRemovePrefixDbSlash_OnlyLeadingSlash() const string subPath = "/"; // Act - string result = PathHelper.RemovePrefixDbSlash(subPath); + var result = PathHelper.RemovePrefixDbSlash(subPath); // Assert Assert.AreEqual(string.Empty, result); @@ -361,4 +346,65 @@ public void TestSplitInputFilePaths_WithValidInput_ReturnsArrayOfStrings() Assert.AreEqual("/path/to/file1", result[0]); Assert.AreEqual("/path/to/file2", result[1]); } + + private const string TestContentVeryLongString = + "this-is-a-really-long-slug-that-goes-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-and-on-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-and-on-and-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-" + + "and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-" + + "and-and-on-and-on-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-and-on-" + + "and-on-and-on-and-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-" + + "and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and" + + "-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on" + + "-and-on-and-on-and-on-and-on-and-and-on-and-on-and-on-and-on-and-on-and-on-and-" + + "on-and-on-and-on-and-and-on-and-and-on-and-on-and-on-and-and-on-and-and-on-and-" + + "on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-on-and-and-on-and" + + "-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and" + + "-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and" + + "-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and" + + "-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and-and"; } From c58913a23e18ff62132f11ad46d1221020ba130a Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 8 Apr 2024 12:15:15 +0200 Subject: [PATCH 7/8] add tests --- .../Helpers/PathHelper.cs | 2 +- .../Helpers/PathHelperTest.cs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs index 4724a78b53..be2ac7808f 100644 --- a/starsky/starsky.foundation.platform/Helpers/PathHelper.cs +++ b/starsky/starsky.foundation.platform/Helpers/PathHelper.cs @@ -32,7 +32,7 @@ public static string GetFileName(string? filePath) [SuppressMessage("Style", "IDE0057:Use range operator")] [SuppressMessage("ReSharper", "ReplaceSliceWithRangeIndexer")] - private static ReadOnlySpan GetFileNameUnix(ReadOnlySpan path) + internal static ReadOnlySpan GetFileNameUnix(ReadOnlySpan path) { var length = GetPathRootUnix(path).Length; var num = path.LastIndexOf('/'); diff --git a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs index 3bdf960786..c6a45fd1b0 100644 --- a/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs +++ b/starsky/starskytest/starsky.foundation.platform/Helpers/PathHelperTest.cs @@ -23,6 +23,20 @@ public void GetFileName_ReturnsValidFileName(string input, string expectedFileNa // Assert Assert.AreEqual(expectedFileName, actualFileName); } + + [DataTestMethod] // [Theory] + [DataRow("path/to/file.txt", "file.txt")] + [DataRow("/test/file/", "")] + [DataRow("/test/file", "file")] // no backslash + [DataRow("", "")] + public void GetFileNameUnix_ReturnsValidFileName(string input, string expectedFileName) + { + // Act + var actualFileName = PathHelper.GetFileNameUnix(input).ToString(); + + // Assert + Assert.AreEqual(expectedFileName, actualFileName); + } [TestMethod] [ExpectedException(typeof(ArgumentException))] From 4175f12bc11066f8cad942f77644446b10e0914a Mon Sep 17 00:00:00 2001 From: Dion Date: Mon, 8 Apr 2024 12:18:38 +0200 Subject: [PATCH 8/8] keep a changelog --- history.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/history.md b/history.md index aa0c01113e..4e99337e6f 100644 --- a/history.md +++ b/history.md @@ -45,7 +45,7 @@ Semantic Versioning 2.0.0 is from version 0.1.6+ - [x] (Changed) _Front-end_ Make prev / next more contrast (PR #1511) - [x] (Fixed) _Docs_ Demo site is not working (PR #1486) -- [x] (Fixed) _Back-end_ GetFileNameRegex give longer to avoid timeouts (PR #1515) +- [x] (Fixed) _Back-end_ GetFileNameRegex refactor to avoid timeouts (PR #1515) ## version 0.6.0 - 2024-03-15 {#v0.6.0}