From c54d2bb18a14e415aa65e6ddf584233a43f4ce17 Mon Sep 17 00:00:00 2001 From: Kenneth Hsu Date: Sun, 12 Aug 2018 19:18:08 -0700 Subject: [PATCH 1/3] Add culture-aware string comparison tests. This concerns issue #3342. --- Duplicati/UnitTest/UtilityTests.cs | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs index 28c0a7991..70e9f261b 100644 --- a/Duplicati/UnitTest/UtilityTests.cs +++ b/Duplicati/UnitTest/UtilityTests.cs @@ -24,6 +24,46 @@ namespace Duplicati.UnitTest { public class UtilityTests { + [Test] + [Category("Utility")] + [TestCase("da-DK")] + [TestCase("en-US")] + [TestCase("hu-HU")] + [TestCase("tr-TR")] + public static void FilenameStringComparison(string cultureName) + { + Action checkStringComparison = (x, y) => Assert.IsFalse(String.Equals(x, y, Utility.ClientFilenameStringComparison)); + Action checkStringComparer = (x, y) => Assert.IsFalse(new HashSet(new[] { x }).Contains(y, Utility.ClientFilenameStringComparer)); + + System.Globalization.CultureInfo originalCulture = System.Globalization.CultureInfo.CurrentCulture; + try + { + System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName, false); + + // These are equivalent with respect to hu-HU, but different with respect to en-US. + string ddzs = "ddzs"; + string dzsdzs = "dzsdzs"; + checkStringComparison(ddzs, dzsdzs); + checkStringComparer(ddzs, dzsdzs); + + // Many cultures treat the following as equivalent. + string eAcuteOneCharacter = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(new byte[] { 233 }); // 'é' as one character (ALT+0233). + string eAcuteTwoCharacters = "\u0065\u0301"; // 'e', combined with an acute accent (U+301). + checkStringComparison(eAcuteOneCharacter, eAcuteTwoCharacters); + checkStringComparer(eAcuteOneCharacter, eAcuteTwoCharacters); + + // These are equivalent with respect to en-US, but different with respect to da-DK. + string aDiaeresisOneCharacter = "\u00C4"; // 'A' with a diaeresis. + string aDiaeresisTwoCharacters = "\u0041\u0308"; // 'A', combined with a diaeresis. + checkStringComparison(aDiaeresisOneCharacter, aDiaeresisTwoCharacters); + checkStringComparer(aDiaeresisOneCharacter, aDiaeresisTwoCharacters); + } + finally + { + System.Threading.Thread.CurrentThread.CurrentCulture = originalCulture; + } + } + [Test] [Category("Utility")] public static void ForceStreamRead() From b45c41026e73f76eede476bf40f709e2bccaa03b Mon Sep 17 00:00:00 2001 From: Kenneth Hsu Date: Sat, 18 Aug 2018 20:25:43 -0700 Subject: [PATCH 2/3] Use ordinal file path comparisons. This addresses issue #3342. --- Duplicati/Library/Utility/Utility.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs index 70d5ff23c..6626ce6a7 100644 --- a/Duplicati/Library/Utility/Utility.cs +++ b/Duplicati/Library/Utility/Utility.cs @@ -1054,12 +1054,12 @@ namespace Duplicati.Library.Utility /// /// Gets a string comparer that matches the client filesystems case sensitivity /// - public static StringComparer ClientFilenameStringComparer => IsFSCaseSensitive ? StringComparer.CurrentCulture : StringComparer.CurrentCultureIgnoreCase; + public static StringComparer ClientFilenameStringComparer => IsFSCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; /// /// Gets the string comparision that matches the client filesystems case sensitivity /// - public static StringComparison ClientFilenameStringComparison => IsFSCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; + public static StringComparison ClientFilenameStringComparison => IsFSCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; /// /// The path to the users home directory From d67c5c393bc0ed0c4a26a569f87772443acaab9d Mon Sep 17 00:00:00 2001 From: Kenneth Hsu Date: Thu, 30 Aug 2018 18:30:54 -0700 Subject: [PATCH 3/3] Fix whitespace issues. --- Duplicati/UnitTest/UtilityTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs index 70e9f261b..f5ce20035 100644 --- a/Duplicati/UnitTest/UtilityTests.cs +++ b/Duplicati/UnitTest/UtilityTests.cs @@ -122,7 +122,7 @@ namespace Duplicati.UnitTest // Test with custom comparer. IEqualityComparer comparer = StringComparer.OrdinalIgnoreCase; - uniqueItems = new string[] {"a", "b", "c"}; + uniqueItems = new string[] { "a", "b", "c" }; duplicateItems = new string[] { "a", "c" }; actualDuplicateItems = null;