Skip to content

Commit

Permalink
Set severity of rule CA1870 to warning (dotnet#92135)
Browse files Browse the repository at this point in the history
* Set severity of rule CA1870 to warning

* Replace one more usage in nativeaot corelib

* Set severity for tests as well

* pragma disable the rule in nativeaot's reflection impl
  • Loading branch information
MihaZupan authored Sep 20, 2023
1 parent 901f780 commit e235aef
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 9 deletions.
3 changes: 3 additions & 0 deletions eng/CodeAnalysis.src.globalconfig
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ dotnet_diagnostic.CA1868.severity = warning
# CA1869: Cache and reuse 'JsonSerializerOptions' instances
dotnet_diagnostic.CA1869.severity = warning

# CA1870: Use a cached 'SearchValues' instance
dotnet_diagnostic.CA1870.severity = warning

# CA2000: Dispose objects before losing scope
dotnet_diagnostic.CA2000.severity = none

Expand Down
3 changes: 3 additions & 0 deletions eng/CodeAnalysis.test.globalconfig
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ dotnet_diagnostic.CA1868.severity = none
# CA1869: Cache and reuse 'JsonSerializerOptions' instances
dotnet_diagnostic.CA1869.severity = none

# CA1870: Use a cached 'SearchValues' instance
dotnet_diagnostic.CA1870.severity = none

# CA2000: Dispose objects before losing scope
dotnet_diagnostic.CA2000.severity = none

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ public static TypeLoadException CreateTypeLoadException(string typeName, string
public static string EscapeTypeNameIdentifier(this string identifier)
{
// Some characters in a type name need to be escaped

// We're avoiding calling into MemoryExtensions here as it has paths that lead to reflection,
// and that would lead to an infinite loop given that this is the implementation of reflection.
#pragma warning disable CA1870 // Use a cached 'SearchValues' instance
if (identifier != null && identifier.IndexOfAny(s_charsToEscape) != -1)
#pragma warning restore CA1870
{
StringBuilder sbEscapedName = new StringBuilder(identifier.Length);
foreach (char c in identifier)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
Expand All @@ -18,6 +19,12 @@ namespace System.Configuration
[DebuggerDisplay("ConfigPath = {ConfigPath}")]
internal abstract class BaseConfigurationRecord : IInternalConfigRecord
{
#if NET8_0_OR_GREATER
private static readonly SearchValues<char> s_invalidSubPathChars = SearchValues.Create(InvalidSubPathCharactersString);
#else
private static ReadOnlySpan<char> s_invalidSubPathChars => InvalidSubPathCharactersString.AsSpan();
#endif

protected const string NewLine = "\r\n";

internal const string KeywordTrue = "true";
Expand Down Expand Up @@ -128,7 +135,6 @@ internal abstract class BaseConfigurationRecord : IInternalConfigRecord

// Comparer used in sorting IndirectInputs.
private static readonly IComparer<SectionInput> s_indirectInputsComparer = new IndirectLocationInputComparer();
private static readonly char[] s_invalidSubPathCharactersArray = InvalidSubPathCharactersString.ToCharArray();
protected Hashtable _children; // configName -> record

private object _configContext; // Context for config level
Expand Down Expand Up @@ -3090,7 +3096,7 @@ internal static string NormalizeLocationSubPath(string subPath, IConfigErrorInfo
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_last_character, errorInfo);

// combination of URI reserved characters and OS invalid filename characters, minus / (allowed reserved character)
if (subPath.IndexOfAny(s_invalidSubPathCharactersArray) != -1)
if (subPath.AsSpan().IndexOfAny(s_invalidSubPathChars) >= 0)
throw new ConfigurationErrorsException(SR.Config_location_path_invalid_character, errorInfo);

return subPath;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
Expand All @@ -11,6 +12,12 @@ namespace System.Reflection.TypeLoading
{
internal static class Helpers
{
#if NET8_0_OR_GREATER
private static readonly SearchValues<char> s_charsToEscape = SearchValues.Create("\\[]+*&,");
#else
private static ReadOnlySpan<char> s_charsToEscape => "\\[]+*&,".AsSpan();
#endif

[return: NotNullIfNotNull(nameof(original))]
public static T[]? CloneArray<T>(this T[]? original)
{
Expand Down Expand Up @@ -96,7 +103,7 @@ public static string ComputeArraySuffix(int rank, bool multiDim)
public static string EscapeTypeNameIdentifier(this string identifier)
{
// Some characters in a type name need to be escaped
if (identifier.IndexOfAny(s_charsToEscape) != -1)
if (TypeNameContainsTypeParserMetacharacters(identifier))
{
StringBuilder sbEscapedName = new StringBuilder(identifier.Length);
foreach (char c in identifier)
Expand All @@ -113,12 +120,16 @@ public static string EscapeTypeNameIdentifier(this string identifier)

public static bool TypeNameContainsTypeParserMetacharacters(this string identifier)
{
return identifier.IndexOfAny(s_charsToEscape) != -1;
return identifier.AsSpan().IndexOfAny(s_charsToEscape) >= 0;
}

public static bool NeedsEscapingInTypeName(this char c)
{
return Array.IndexOf(s_charsToEscape, c) >= 0;
#if NET8_0_OR_GREATER
return s_charsToEscape.Contains(c);
#else
return s_charsToEscape.IndexOf(c) >= 0;
#endif
}

public static string UnescapeTypeNameIdentifier(this string identifier)
Expand All @@ -145,8 +156,6 @@ public static string UnescapeTypeNameIdentifier(this string identifier)
return identifier;
}

private static readonly char[] s_charsToEscape = new char[] { '\\', '[', ']', '+', '*', '&', ',' };

/// <summary>
/// For AssemblyReferences, convert "unspecified" components from the ECMA format (0xffff) to the in-memory System.Version format (0xffffffff).
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Speech.Internal;
Expand All @@ -14,6 +15,8 @@ namespace System.Speech.Recognition.SrgsGrammar
[DebuggerTypeProxy(typeof(SrgsRuleDebugDisplay))]
public class SrgsRule : IRule
{
private static readonly SearchValues<char> s_invalidChars = SearchValues.Create("?*+|()^$/;.=<>[]{}\\ \t\r\n");

#region Constructors
private SrgsRule()
{
Expand Down Expand Up @@ -383,7 +386,7 @@ private void ValidateIdentifier(string s)
XmlParser.ThrowSrgsException(SRID.ConstructorNotAllowed, _id);
}

if (s != null && (s.IndexOfAny(s_invalidChars) >= 0 || s.Length == 0))
if (s != null && (s.Length == 0 || s.AsSpan().ContainsAny(s_invalidChars)))
{
XmlParser.ThrowSrgsException(SRID.InvalidMethodName);
}
Expand Down Expand Up @@ -416,7 +419,6 @@ private void ValidateIdentifier(string s)
private string _onError;

private string _onRecognition;
private static readonly char[] s_invalidChars = new char[] { '?', '*', '+', '|', '(', ')', '^', '$', '/', ';', '.', '=', '<', '>', '[', ']', '{', '}', '\\', ' ', '\t', '\r', '\n' };

#endregion

Expand Down

0 comments on commit e235aef

Please sign in to comment.