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 diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs index 28c0a7991..f5ce20035 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() @@ -82,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;