protected override ImmutableArray <ISymbol> GetSpecialIncompatibleMembers(Compilation compilation) { var dangerousPatternsBuilder = ImmutableArray.CreateBuilder <ISymbol> (); var assemblyType = compilation.GetTypeByMetadataName("System.Reflection.Assembly"); if (assemblyType != null) { // properties ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyType.GetMembers("Location"))); // methods dangerousPatternsBuilder.AddRange(assemblyType.GetMembers("GetFile").OfType <IMethodSymbol> ()); dangerousPatternsBuilder.AddRange(assemblyType.GetMembers("GetFiles").OfType <IMethodSymbol> ()); } var assemblyNameType = compilation.GetTypeByMetadataName("System.Reflection.AssemblyName"); if (assemblyNameType != null) { ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyNameType.GetMembers("CodeBase"))); ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyNameType.GetMembers("EscapedCodeBase"))); } return(dangerousPatternsBuilder.ToImmutable()); }
protected override bool ReportSpecialIncompatibleMembersDiagnostic(OperationAnalysisContext operationContext, ImmutableArray <ISymbol> dangerousPatterns, ISymbol member) { if (member is IMethodSymbol && ImmutableArrayOperations.Contains(dangerousPatterns, member, SymbolEqualityComparer.Default)) { operationContext.ReportDiagnostic(Diagnostic.Create(s_getFilesRule, operationContext.Operation.Syntax.GetLocation(), member.GetDisplayName())); return(true); } else if (member is IPropertySymbol && ImmutableArrayOperations.Contains(dangerousPatterns, member, SymbolEqualityComparer.Default)) { operationContext.ReportDiagnostic(Diagnostic.Create(s_locationRule, operationContext.Operation.Syntax.GetLocation(), member.GetDisplayName())); return(true); } return(false); }
static void CheckCalledMember( OperationAnalysisContext operationContext, ISymbol member, ImmutableArray <ISymbol> dangerousPatterns) { // Do not emit any diagnostic if caller is annotated with the attribute too. if (operationContext.ContainingSymbol.HasAttribute(RequiresAssemblyFilesAttribute)) { return; } // In case ContainingSymbol is a property accesor check also for RequiresAssemblyFilesAttribute in the associated property if (operationContext.ContainingSymbol is IMethodSymbol containingSymbol && (containingSymbol.MethodKind == MethodKind.PropertyGet || containingSymbol.MethodKind == MethodKind.PropertySet) && containingSymbol.AssociatedSymbol !.HasAttribute(RequiresAssemblyFilesAttribute)) { return; } if (member is IMethodSymbol && ImmutableArrayOperations.Contains(dangerousPatterns, member, SymbolEqualityComparer.Default)) { operationContext.ReportDiagnostic(Diagnostic.Create(s_getFilesRule, operationContext.Operation.Syntax.GetLocation(), member)); return; } else if (member is IPropertySymbol && ImmutableArrayOperations.Contains(dangerousPatterns, member, SymbolEqualityComparer.Default)) { operationContext.ReportDiagnostic(Diagnostic.Create(s_locationRule, operationContext.Operation.Syntax.GetLocation(), member)); return; } if (member.TryGetRequiresAssemblyFileAttribute(out AttributeData? requiresAssemblyFilesAttribute)) { var message = requiresAssemblyFilesAttribute?.NamedArguments.FirstOrDefault(na => na.Key == "Message").Value.Value?.ToString(); message = message != null ? " " + message + "." : message; var url = requiresAssemblyFilesAttribute?.NamedArguments.FirstOrDefault(na => na.Key == "Url").Value.Value?.ToString(); url = url != null ? " " + url : url; operationContext.ReportDiagnostic(Diagnostic.Create( s_requiresAssemblyFilesRule, operationContext.Operation.Syntax.GetLocation(), member.OriginalDefinition.ToString(), message, url)); } }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction(context => { var compilation = context.Compilation; var isSingleFileAnalyzerEnabled = context.Options.GetMSBuildPropertyValue(MSBuildPropertyOptionNames.EnableSingleFileAnalyzer, compilation); if (!string.Equals(isSingleFileAnalyzerEnabled?.Trim(), "true", StringComparison.OrdinalIgnoreCase)) { return; } var includesAllContent = context.Options.GetMSBuildPropertyValue(MSBuildPropertyOptionNames.IncludeAllContentForSelfExtract, compilation); if (string.Equals(includesAllContent?.Trim(), "true", StringComparison.OrdinalIgnoreCase)) { return; } var dangerousPatternsBuilder = ImmutableArray.CreateBuilder <ISymbol> (); var assemblyType = compilation.GetTypeByMetadataName("System.Reflection.Assembly"); if (assemblyType != null) { // properties ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyType.GetMembers("Location"))); // methods dangerousPatternsBuilder.AddRange(assemblyType.GetMembers("GetFile").OfType <IMethodSymbol> ()); dangerousPatternsBuilder.AddRange(assemblyType.GetMembers("GetFiles").OfType <IMethodSymbol> ()); } var assemblyNameType = compilation.GetTypeByMetadataName("System.Reflection.AssemblyName"); if (assemblyNameType != null) { ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyNameType.GetMembers("CodeBase"))); ImmutableArrayOperations.AddIfNotNull(dangerousPatternsBuilder, ImmutableArrayOperations.TryGetSingleSymbol <IPropertySymbol> (assemblyNameType.GetMembers("EscapedCodeBase"))); } var dangerousPatterns = dangerousPatternsBuilder.ToImmutable(); context.RegisterOperationAction(operationContext => { var methodInvocation = (IInvocationOperation)operationContext.Operation; CheckCalledMember(operationContext, methodInvocation.TargetMethod, dangerousPatterns); }, OperationKind.Invocation); context.RegisterOperationAction(operationContext => { var objectCreation = (IObjectCreationOperation)operationContext.Operation; var ctor = objectCreation.Constructor; if (ctor is not null) { CheckCalledMember(operationContext, ctor, dangerousPatterns); } }, OperationKind.ObjectCreation); context.RegisterOperationAction(operationContext => { var propAccess = (IPropertyReferenceOperation)operationContext.Operation; var prop = propAccess.Property; var usageInfo = propAccess.GetValueUsageInfo(prop); if (usageInfo.HasFlag(ValueUsageInfo.Read) && prop.GetMethod != null) { CheckCalledMember(operationContext, prop.GetMethod, dangerousPatterns); } if (usageInfo.HasFlag(ValueUsageInfo.Write) && prop.SetMethod != null) { CheckCalledMember(operationContext, prop.SetMethod, dangerousPatterns); } CheckCalledMember(operationContext, prop, dangerousPatterns); }, OperationKind.PropertyReference); context.RegisterOperationAction(operationContext => { var eventRef = (IEventReferenceOperation)operationContext.Operation; CheckCalledMember(operationContext, eventRef.Member, dangerousPatterns); }, OperationKind.EventReference);