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;