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
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