| File: Microsoft.NetCore.Analyzers\Security\UseXmlReaderBase.cs | Web Access |
| Project: src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.NetAnalyzers\Microsoft.CodeAnalysis.NetAnalyzers.csproj (Microsoft.CodeAnalysis.NetAnalyzers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Immutable; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.NetCore.Analyzers.Security { using static MicrosoftNetCoreAnalyzersResources; public abstract class UseXmlReaderBase : DiagnosticAnalyzer { /// <summary> /// Metadata name of the type which is recommended to use method take XmlReader as parameter. /// </summary> protected abstract string TypeMetadataName { get; } /// <summary> /// Metadata name of the method which is recommended to use XmlReader as parameter. /// </summary> protected abstract string MethodMetadataName { get; } protected abstract DiagnosticDescriptor Rule { get; } public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule); protected static LocalizableString Description { get; } = CreateLocalizableResourceString(nameof(UseXmlReaderDescription)); protected static LocalizableString Message { get; } = CreateLocalizableResourceString(nameof(UseXmlReaderMessage)); public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction(compilationStartAnalysisContext => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( TypeMetadataName, out INamedTypeSymbol? xmlSchemaTypeSymbol)) { return; } INamedTypeSymbol? xmlReaderTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemXmlXmlReader); compilationStartAnalysisContext.RegisterOperationAction(operationAnalysisContext => { var operation = operationAnalysisContext.Operation; IMethodSymbol? methodSymbol = null; string? methodName = null; switch (operation.Kind) { case OperationKind.Invocation: methodSymbol = ((IInvocationOperation)operation).TargetMethod; methodName = methodSymbol.Name; break; case OperationKind.ObjectCreation: methodSymbol = ((IObjectCreationOperation)operation).Constructor; if (methodSymbol == null) return; methodName = methodSymbol.ContainingType.Name; break; default: return; } if (methodName.StartsWith(MethodMetadataName, StringComparison.Ordinal) && methodSymbol.IsOverrideOrVirtualMethodOf(xmlSchemaTypeSymbol)) { if (xmlReaderTypeSymbol != null && !methodSymbol.Parameters.IsEmpty && methodSymbol.Parameters[0].Type.Equals(xmlReaderTypeSymbol)) { return; } operationAnalysisContext.ReportDiagnostic( operation.CreateDiagnostic( Rule, methodSymbol.ContainingType.Name, methodName)); } }, OperationKind.Invocation, OperationKind.ObjectCreation); }); } } }