Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -439,5 +439,14 @@ public void TestCreationWithTemporaryLCID(int lcid)

Assert.NotEqual(lcid, new CultureInfo(lcid).LCID);
}

[InlineData("zh-TW-u-co-zhuyin")]
[InlineData("de-DE-u-co-phoneb")]
[InlineData("de-u-co-phonebk")]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
public void TestCreationWithMangledSortName(string cultureName)
{
Assert.True(CultureInfo.GetCultureInfo(cultureName).CompareInfo.Name.Equals(cultureName, StringComparison.OrdinalIgnoreCase));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public partial class CompareInfo
[NonSerialized]
private bool _isAsciiEqualityOrdinal;

private void IcuInitSortHandle()
private void IcuInitSortHandle(string interopCultureName)
{
if (GlobalizationMode.Invariant)
{
Expand All @@ -23,6 +23,7 @@ private void IcuInitSortHandle()
else
{
Debug.Assert(!GlobalizationMode.UseNls);
Debug.Assert(interopCultureName != null);

// Inline the following condition to avoid potential implementation cycles within globalization
//
Expand All @@ -31,7 +32,7 @@ private void IcuInitSortHandle()
_isAsciiEqualityOrdinal = _sortName.Length == 0 ||
(_sortName.Length >= 2 && _sortName[0] == 'e' && _sortName[1] == 'n' && (_sortName.Length == 2 || _sortName[2] == '-'));

_sortHandle = SortHandleCache.GetCachedSortHandle(_sortName);
_sortHandle = SortHandleCache.GetCachedSortHandle(interopCultureName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private void InitSort(CultureInfo culture)
}
else
{
IcuInitSortHandle();
IcuInitSortHandle(culture.InteropName!);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ private bool InitIcuCultureDataCore()
index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
if (index >= 0)
{
_sName = string.Concat(_sWindowsName.AsSpan(0, index), "_", alternateSortName);
// Use original culture name if alternateSortName is not set, which is possible even if the normalized
// culture name has "@collation=".
// "zh-TW-u-co-zhuyin" is a good example. The term "u-co-" means the following part will be the sort name
// and it will be treated in ICU as "zh-TW@collation=zhuyin".
_sName = alternateSortName.Length == 0 ? realNameBuffer : string.Concat(_sWindowsName.AsSpan(0, index), "_", alternateSortName);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,12 @@ internal sealed partial class CultureData
private static volatile Dictionary<string, CultureData>? s_cachedRegions;
private static volatile Dictionary<string, string>? s_regionNames;

/// <summary>
/// The culture name to use to interop with the underlying native globalization libraries like ICU or Windows NLS APIs.
/// For example, we can have the name de_DE@collation=phonebook when using ICU for the German culture de-DE with the phonebook sorting behavior.
/// </summary>
internal string? InteropName => _sWindowsName;

internal static CultureData? GetCultureDataForRegion(string? cultureName, bool useUserOverride)
{
// First do a shortcut for Invariant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,12 @@ public static CultureInfo[] GetCultures(CultureTypes types)
/// </summary>
internal string SortName => _sortName ??= _cultureData.SortName;

/// <summary>
/// The culture name to use to interop with the underlying native globalization libraries like ICU or Windows NLS APIs.
/// For example, we can have the name de_DE@collation=phonebook when using ICU for the German culture de-DE with the phonebook sorting behavior.
/// </summary>
internal string? InteropName => _cultureData.InteropName;

public string IetfLanguageTag =>
// special case the compatibility cultures
Name switch
Expand Down