* Port the servicing fix
This is porting the servcing fix https://github.com/dotnet/coreclr/commit/
8ce622d569fae9feb160399db03dc2b86577be1b with a small change to get rid of unsafe code in CultureData per Jan recommendation
* remove un-needed lines
* rename the variable name as it is not a pointer anymore
using StringList = List<string>;
#else
using StringList = LowLevelList<string>;
using StringList = List<string>;
#else
using StringList = LowLevelList<string>;
internal partial class CultureData
{
internal partial class CultureData
{
- // Enumerate all system cultures and then try to find out which culture has
+ // Enumerate all system cultures and then try to find out which culture has
// region name match the requested region name
private static CultureData GetCultureDataFromRegionName(String regionName)
{
// region name match the requested region name
private static CultureData GetCultureDataFromRegionName(String regionName)
{
+ Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(regionName != null);
const uint LOCALE_SUPPLEMENTAL = 0x00000002;
Debug.Assert(regionName != null);
const uint LOCALE_SUPPLEMENTAL = 0x00000002;
#if ENABLE_WINRT
return WinRTInterop.Callbacks.GetRegionDisplayName(isoCountryCode);
#else
#if ENABLE_WINRT
return WinRTInterop.Callbacks.GetRegionDisplayName(isoCountryCode);
#else
- // If the current UI culture matching the OS UI language, we'll get the display name from the OS.
+ // If the current UI culture matching the OS UI language, we'll get the display name from the OS.
// otherwise, we use the native name as we don't carry resources for the region display names anyway.
if (CultureInfo.CurrentUICulture.Name.Equals(CultureInfo.UserDefaultUICulture.Name))
{
// otherwise, we use the native name as we don't carry resources for the region display names anyway.
if (CultureInfo.CurrentUICulture.Name.Equals(CultureInfo.UserDefaultUICulture.Name))
{
private static CultureInfo[] EnumCultures(CultureTypes types)
{
Debug.Assert(!GlobalizationMode.Invariant);
private static CultureInfo[] EnumCultures(CultureTypes types)
{
Debug.Assert(!GlobalizationMode.Invariant);
uint flags = 0;
#pragma warning disable 618
uint flags = 0;
#pragma warning disable 618
cultures[i] = new CultureInfo(context.strings[i]);
}
cultures[i] = new CultureInfo(context.strings[i]);
}
}
private string GetConsoleFallbackName(string cultureName)
}
private string GetConsoleFallbackName(string cultureName)
}
// If not found in the hard coded table we'll have to find a culture that works for us
}
// If not found in the hard coded table we'll have to find a culture that works for us
- if (retVal == null || (retVal.IsNeutralCulture == true))
+ if (!GlobalizationMode.Invariant && (retVal == null || (retVal.IsNeutralCulture == true)))
{
retVal = GetCultureDataFromRegionName(cultureName);
}
{
retVal = GetCultureDataFromRegionName(cultureName);
}
CultureTypes.ReplacementCultures | CultureTypes.WindowsOnlyCultures |
CultureTypes.FrameworkCultures)) != 0)
{
CultureTypes.ReplacementCultures | CultureTypes.WindowsOnlyCultures |
CultureTypes.FrameworkCultures)) != 0)
{
- throw new ArgumentOutOfRangeException(nameof(types),
+ throw new ArgumentOutOfRangeException(nameof(types),
SR.Format(SR.ArgumentOutOfRange_Range, CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
}
SR.Format(SR.ArgumentOutOfRange_Range, CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
}
// Remove the enum as it is an no-op.
types &= (~CultureTypes.WindowsOnlyCultures);
}
// Remove the enum as it is an no-op.
types &= (~CultureTypes.WindowsOnlyCultures);
}
if (GlobalizationMode.Invariant)
{
// in invariant mode we always return invariant culture only from the enumeration
if (GlobalizationMode.Invariant)
{
// in invariant mode we always return invariant culture only from the enumeration
invariant._iDefaultOemCodePage = 437; // default oem code page ID (OCP or OEM)
invariant._iDefaultMacCodePage = 10000; // default macintosh code page
invariant._iDefaultEbcdicCodePage = 037; // default EBCDIC code page
invariant._iDefaultOemCodePage = 437; // default oem code page ID (OCP or OEM)
invariant._iDefaultMacCodePage = 10000; // default macintosh code page
invariant._iDefaultEbcdicCodePage = 037; // default EBCDIC code page
if (GlobalizationMode.Invariant)
{
invariant._sLocalizedDisplayName = invariant._sNativeDisplayName;
if (GlobalizationMode.Invariant)
{
invariant._sLocalizedDisplayName = invariant._sNativeDisplayName;
- private static unsafe string NormalizeCultureName(string name, out bool isNeutralName)
+ private static string NormalizeCultureName(string name, out bool isNeutralName)
{
isNeutralName = true;
int i = 0;
{
isNeutralName = true;
int i = 0;
- Debug.Assert(name.Length <= LOCALE_NAME_MAX_LENGTH);
+ if (name.Length > LOCALE_NAME_MAX_LENGTH)
+ {
+ // Theoretically we shouldn't hit this exception.
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidId, nameof(name)));
+ }
+
+ Span<char> normalizedName = stackalloc char[name.Length];
- char *pName = stackalloc char[LOCALE_NAME_MAX_LENGTH];
bool changed = false;
while (i < name.Length && name[i] != '-' && name[i] != '_')
bool changed = false;
while (i < name.Length && name[i] != '-' && name[i] != '_')
if (name[i] >= 'A' && name[i] <= 'Z')
{
// lowercase characters before '-'
if (name[i] >= 'A' && name[i] <= 'Z')
{
// lowercase characters before '-'
- pName[i] = (char) (((int)name[i]) + 0x20);
+ normalizedName[i] = (char) (((int)name[i]) + 0x20);
+ normalizedName[i] = name[i];
{
if (name[i] >= 'a' && name[i] <= 'z')
{
{
if (name[i] >= 'a' && name[i] <= 'z')
{
- pName[i] = (char) (((int)name[i]) - 0x20);
+ normalizedName[i] = (char) (((int)name[i]) - 0x20);
+ normalizedName[i] = name[i];
- return new string(pName, 0, name.Length);
-
+ return new string(normalizedName);
+
{
if (GlobalizationMode.Invariant)
{
{
if (GlobalizationMode.Invariant)
{
- CultureInfo.VerifyCultureName(cultureName, true);
+ if (cultureName.Length > LOCALE_NAME_MAX_LENGTH || !CultureInfo.VerifyCultureName(cultureName, false))
+ {
+ return null;
+ }
CultureData cd = CreateCultureWithInvariantData();
cd._bUseOverrides = useUserOverride;
cd._sName = NormalizeCultureName(cultureName, out cd._bNeutral);
CultureData cd = CreateCultureWithInvariantData();
cd._bUseOverrides = useUserOverride;
cd._sName = NormalizeCultureName(cultureName, out cd._bNeutral);
if (culture == CultureInfo.LOCALE_INVARIANT)
return Invariant;
if (culture == CultureInfo.LOCALE_INVARIANT)
return Invariant;
if (GlobalizationMode.Invariant)
{
// LCID is not supported in the InvariantMode
if (GlobalizationMode.Invariant)
{
// LCID is not supported in the InvariantMode
- // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
// if DefaultThreadCurrentUICulture was set
CultureInfo ci;
// if DefaultThreadCurrentUICulture was set
CultureInfo ci;
{
if (_sLocalizedLanguage == null)
{
{
if (_sLocalizedLanguage == null)
{
- // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
// if DefaultThreadCurrentUICulture was set
CultureInfo ci;
// if DefaultThreadCurrentUICulture was set
CultureInfo ci;
- // do nothing. we'll fallback
+ // do nothing. we'll fallback
}
if (_sLocalizedCountry == null)
}
if (_sLocalizedCountry == null)
// This is ONLY used for caching names and shouldn't be used for anything else
internal static string AnsiToLower(string testString)
{
// This is ONLY used for caching names and shouldn't be used for anything else
internal static string AnsiToLower(string testString)
{
while (index<testString.Length && (testString[index]<'A' || testString[index]>'Z' ))
{
index++;
while (index<testString.Length && (testString[index]<'A' || testString[index]>'Z' ))
{
index++;
{
return testString; // we didn't really change the string
}
{
return testString; // we didn't really change the string
}
StringBuilder sb = new StringBuilder(testString.Length);
for (int i=0; i<index; i++)
{
StringBuilder sb = new StringBuilder(testString.Length);
for (int i=0; i<index; i++)
{