From 298dbb86b3342e1aef7131d84ef95c841a06cdcc Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Wed, 12 Aug 2020 09:12:41 +0100 Subject: [PATCH 1/4] Use string.Compare Use `string.Compare` static method instead of `CompareInfo.Compare` instance method --- .../commands/utility/ObjectCommandComparer.cs | 2 +- .../engine/Attributes.cs | 4 ++-- .../engine/LanguagePrimitives.cs | 6 +++--- .../engine/runtime/Operations/StringOps.cs | 18 ++---------------- .../namespaces/FileSystemProvider.cs | 2 +- 5 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs index fd69a2011fb..c58b8a1a3e9 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs @@ -222,7 +222,7 @@ public int Compare(object first, object second) string firstString = PSObject.AsPSObject(first).ToString(); string secondString = PSObject.AsPSObject(second).ToString(); - return _cultureInfo.CompareInfo.Compare(firstString, secondString, _caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase) * (_ascendingOrder ? 1 : -1); + return string.Compare(firstString, secondString, _cultureInfo, _caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase) * (_ascendingOrder ? 1 : -1); } private CultureInfo _cultureInfo = null; diff --git a/src/System.Management.Automation/engine/Attributes.cs b/src/System.Management.Automation/engine/Attributes.cs index 16445703030..6e51759c64e 100644 --- a/src/System.Management.Automation/engine/Attributes.cs +++ b/src/System.Management.Automation/engine/Attributes.cs @@ -1663,10 +1663,10 @@ protected override void ValidateElement(object element) string objString = element.ToString(); foreach (string setString in ValidValues) { - if (CultureInfo.InvariantCulture.CompareInfo.Compare( + if (string.Compare( setString, objString, - IgnoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0) + IgnoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture) == 0) { return; } diff --git a/src/System.Management.Automation/engine/LanguagePrimitives.cs b/src/System.Management.Automation/engine/LanguagePrimitives.cs index 5929a5637e9..d870f7191d0 100644 --- a/src/System.Management.Automation/engine/LanguagePrimitives.cs +++ b/src/System.Management.Automation/engine/LanguagePrimitives.cs @@ -661,7 +661,7 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP if (firstString != null) { secondString = second as string ?? (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture); - return (culture.CompareInfo.Compare(firstString, secondString, + return (string.Compare(firstString, secondString, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0); } @@ -820,7 +820,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP } } - return culture.CompareInfo.Compare(firstString, secondString, + return string.Compare(firstString, secondString, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); } @@ -944,7 +944,7 @@ public static bool TryCompare(object first, object second, bool ignoreCase, IFor } } - result = culture.CompareInfo.Compare(firstString, secondString, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + result = string.Compare(firstString, secondString, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); return true; } diff --git a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs index 0c4658cc14d..6c5340c140b 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs @@ -84,28 +84,14 @@ internal static string FormatOperator(string formatString, object formatArgs) // The following methods are used for the compatibility purpose between regular PowerShell and PowerShell on CSS - /// - /// StringComparison.InvariantCulture is not in CoreCLR, so we need to use - /// CultureInfo.InvariantCulture.CompareInfo.Compare(string, string, CompareOptions) - /// to substitute - /// string.Compare(string, string, StringComparison) - /// internal static int Compare(string strA, string strB, CultureInfo culture, CompareOptions option) { - Diagnostics.Assert(culture != null, "Caller makes sure that 'culture' is not null."); - return culture.CompareInfo.Compare(strA, strB, option); + return string.Compare(strA, strB, culture, option); } - /// - /// StringComparison.InvariantCulture is not in CoreCLR, so we need to use - /// CultureInfo.InvariantCulture.CompareInfo.Compare(string, string, CompareOptions) == 0 - /// to substitute - /// string.Equals(string, string, StringComparison) - /// internal static bool Equals(string strA, string strB, CultureInfo culture, CompareOptions option) { - Diagnostics.Assert(culture != null, "Caller makes sure that 'culture' is not null."); - return culture.CompareInfo.Compare(strA, strB, option) == 0; + return string.Compare(strA, strB, culture, option) == 0; } } } diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index be4b95dc935..a2e746b8363 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -6486,7 +6486,7 @@ public void ClearProperty( // Only the attributes property can be cleared if (propertiesToClear.Count > 1 || - Host.CurrentCulture.CompareInfo.Compare("Attributes", propertiesToClear[0], CompareOptions.IgnoreCase) != 0) + string.Compare("Attributes", propertiesToClear[0], Host.CurrentCulture, CompareOptions.IgnoreCase) != 0) { throw PSTraceSource.NewArgumentException(nameof(propertiesToClear), FileSystemProviderStrings.CannotClearProperty); } From 1c13c235ace97b6f5b41983e6bd0040fe25627da Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Wed, 12 Aug 2020 09:26:34 +0100 Subject: [PATCH 2/4] Wrap arguments for clarity --- .../commands/utility/ObjectCommandComparer.cs | 6 +++++- .../engine/LanguagePrimitives.cs | 21 ++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs index c58b8a1a3e9..ea2632391ce 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs @@ -222,7 +222,11 @@ public int Compare(object first, object second) string firstString = PSObject.AsPSObject(first).ToString(); string secondString = PSObject.AsPSObject(second).ToString(); - return string.Compare(firstString, secondString, _cultureInfo, _caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase) * (_ascendingOrder ? 1 : -1); + return string.Compare( + firstString, + secondString, + _cultureInfo, + _caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase) * (_ascendingOrder ? 1 : -1); } private CultureInfo _cultureInfo = null; diff --git a/src/System.Management.Automation/engine/LanguagePrimitives.cs b/src/System.Management.Automation/engine/LanguagePrimitives.cs index d870f7191d0..0cc3b2177b5 100644 --- a/src/System.Management.Automation/engine/LanguagePrimitives.cs +++ b/src/System.Management.Automation/engine/LanguagePrimitives.cs @@ -661,8 +661,11 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP if (firstString != null) { secondString = second as string ?? (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture); - return (string.Compare(firstString, secondString, culture, - ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0); + return string.Compare( + firstString, + secondString, + culture, + ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0; } if (first.Equals(second)) return true; @@ -820,8 +823,11 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP } } - return string.Compare(firstString, secondString, culture, - ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + return string.Compare( + firstString, + secondString, + culture, + ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); } Type firstType = first.GetType(); @@ -944,7 +950,12 @@ public static bool TryCompare(object first, object second, bool ignoreCase, IFor } } - result = string.Compare(firstString, secondString, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + result = string.Compare( + firstString, + secondString, + culture, + ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + return true; } From fd6af4acbe063bc10cce102c4fb07fd9fd2e044d Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Wed, 12 Aug 2020 09:38:03 +0100 Subject: [PATCH 3/4] Use StringComparison.Ordinal for culture-agnostic string matching --- src/System.Management.Automation/engine/Attributes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/Attributes.cs b/src/System.Management.Automation/engine/Attributes.cs index 6e51759c64e..352d72fd5d9 100644 --- a/src/System.Management.Automation/engine/Attributes.cs +++ b/src/System.Management.Automation/engine/Attributes.cs @@ -1666,7 +1666,7 @@ protected override void ValidateElement(object element) if (string.Compare( setString, objString, - IgnoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture) == 0) + IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0) { return; } From a1be291e45ea0c8fce621d9cacc60a423ec1535f Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Fri, 23 Oct 2020 00:05:01 +0100 Subject: [PATCH 4/4] Fix CodeFactor issue --- .../engine/runtime/Operations/StringOps.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs index 6c5340c140b..91c6d5b545b 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/StringOps.cs @@ -82,13 +82,17 @@ internal static string FormatOperator(string formatString, object formatArgs) } } - // The following methods are used for the compatibility purpose between regular PowerShell and PowerShell on CSS - + /// + /// This method is used for the compatibility purpose between regular PowerShell and PowerShell on CSS + /// internal static int Compare(string strA, string strB, CultureInfo culture, CompareOptions option) { return string.Compare(strA, strB, culture, option); } + /// + /// This method is used for the compatibility purpose between regular PowerShell and PowerShell on CSS + /// internal static bool Equals(string strA, string strB, CultureInfo culture, CompareOptions option) { return string.Compare(strA, strB, culture, option) == 0;