/// <summary> /// Constructor. /// </summary> /// <param name="dfg">DataFlowGraph</param> internal TaintTrackingAnalysis(IGraph <IDataFlowNode> dfg) { this.AnalysisContext = dfg.EntryNode.Summary.AnalysisContext; this.SemanticModel = dfg.EntryNode.Summary.SemanticModel; this.Summary = dfg.EntryNode.Summary; this.DataFlowGraph = dfg; }
/// <summary> /// Constructor. /// </summary> /// <param name="dfg">DataFlowGraph</param> internal TaintTrackingAnalysis(IGraph<IDataFlowNode> dfg) { this.AnalysisContext = dfg.EntryNode.Summary.AnalysisContext; this.SemanticModel = dfg.EntryNode.Summary.SemanticModel; this.Summary = dfg.EntryNode.Summary; this.DataFlowGraph = dfg; }
/// <summary> /// Resolves the side-effects in the call. /// </summary> /// <param name="argumentList">Argument list</param> /// <param name="calleeSummary">Callee MethodSummary</param> /// <param name="node">IDataFlowNode</param> /// <returns>Set of side-effects</returns> private IDictionary <IFieldSymbol, ISet <ISymbol> > ResolveSideEffectsInCall(ArgumentListSyntax argumentList, MethodSummary calleeSummary, IDataFlowNode node) { var sideEffects = new Dictionary <IFieldSymbol, ISet <ISymbol> >(); foreach (var sideEffect in calleeSummary.SideEffectsInfo.FieldFlowParamIndexes) { foreach (var index in sideEffect.Value) { var argExpr = argumentList.Arguments[index].Expression; if (argExpr is IdentifierNameSyntax || argExpr is MemberAccessExpressionSyntax) { var argType = node.Summary.SemanticModel.GetTypeInfo(argExpr).Type; if (this.AnalysisContext.IsTypePassedByValueOrImmutable(argType)) { continue; } IdentifierNameSyntax argIdentifier = this.AnalysisContext.GetRootIdentifier(argExpr); if (!sideEffects.ContainsKey(sideEffect.Key)) { sideEffects.Add(sideEffect.Key, new HashSet <ISymbol>()); } sideEffects[sideEffect.Key].Add(node.Summary.SemanticModel.GetSymbolInfo(argIdentifier).Symbol); } } } return(sideEffects); }
/// <summary> /// Resolves the side-effects in the call. /// </summary> /// <param name="call">ExpressionSyntax</param> /// <param name="calleeSummary">MethodSummary</param> /// <param name="node">IDataFlowNode</param> private void ResolveSideEffectsInCall(ExpressionSyntax call, MethodSummary calleeSummary, IDataFlowNode node) { var invocation = call as InvocationExpressionSyntax; var objCreation = call as ObjectCreationExpressionSyntax; if (calleeSummary == null || (invocation == null && objCreation == null)) { return; } ArgumentListSyntax argumentList; if (invocation != null) { argumentList = invocation.ArgumentList; } else { argumentList = objCreation.ArgumentList; } var sideEffects = this.ResolveSideEffectsInCall(argumentList, calleeSummary, node); foreach (var sideEffect in sideEffects) { node.DataFlowInfo.KillDefinitions(sideEffect.Key); SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(sideEffect.Key); node.DataFlowInfo.AssignTypeToDefinition(sideEffect.Key.Type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); foreach (var symbol in sideEffect.Value) { node.DataFlowInfo.TaintSymbol(symbol, sideEffect.Key); } } for (int index = 0; index < argumentList.Arguments.Count; index++) { if (!calleeSummary.SideEffectsInfo.ParameterAccesses.ContainsKey(index)) { continue; } var argIdentifier = this.AnalysisContext.GetRootIdentifier( argumentList.Arguments[index].Expression); this.ResolveMethodParameterAccesses(argIdentifier, calleeSummary.SideEffectsInfo.ParameterAccesses[index], node); } foreach (var fieldAccess in calleeSummary.SideEffectsInfo.FieldAccesses) { foreach (var access in fieldAccess.Value) { this.MapFieldAccessInStatement(fieldAccess.Key as IFieldSymbol, access); } } }
/// <summary> /// Creates the control-flow graph nodes of the /// specified method summary. /// </summary> /// <param name="dfg">DataFlowGraph</param> /// <param name="summary">MethodSummary</param> /// <returns>IDataFlowNode</returns> internal static IDataFlowNode Create(DataFlowGraph dfg, MethodSummary summary) { var entryNode = new DataFlowNode(dfg, summary.ControlFlowGraph.EntryNode, summary); entryNode.Construct(summary.ControlFlowGraph.EntryNode, null, new Dictionary <IControlFlowNode, DataFlowNode>()); return(entryNode); }
/// <summary> /// Resolves the gives-up ownership information in the call. /// </summary> /// <param name="callSymbol">Symbol</param> /// <param name="methodSummary">MethodSummary</param> /// <param name="argumentList">ArgumentListSyntax</param> /// <param name="node">IDataFlowNode</param> private void ResolveGivesUpOwnershipInCall(ISymbol callSymbol, MethodSummary methodSummary, ArgumentListSyntax argumentList, IDataFlowNode node) { foreach (var paramIndex in methodSummary.SideEffectsInfo.GivesUpOwnershipParamIndexes) { var argExpr = argumentList.Arguments[paramIndex].Expression; this.ResolveGivesUpOwnershipInArgument(callSymbol, argExpr, node); } }
/// <summary> /// Constructor. /// </summary> /// <param name="summary">MethodSummary</param> internal DataFlowGraph(MethodSummary summary) : base() { this.Summary = summary; this.SemanticModel = summary.SemanticModel; base.EntryNode = DataFlowNode.Create(this, summary); base.MergeEmptyNodes(); }
/// <summary> /// Creates the control-flow graph nodes of the /// specified method summary. /// </summary> /// <param name="cfg">ControlFlowGraph</param> /// <param name="summary">MethodSummary</param> /// <returns>IControlFlowNode</returns> internal static IControlFlowNode Create(ControlFlowGraph cfg, MethodSummary summary) { var entryNode = new ControlFlowNode(cfg, summary); entryNode.Statements.Add(Statement.Create(summary.Method.ParameterList, entryNode, summary)); entryNode.Construct(entryNode.GetStatements(summary.Method.Body), null, null); return(entryNode); }
/// <summary> /// Maps the callee summary to the call symbol. /// </summary> /// <param name="calleeSummary">MethodSummary</param> /// <param name="callSymbol">Symbol</param> /// <param name="node">IDataFlowNode</param> private void MapCalleeSummaryToCallSymbol(MethodSummary calleeSummary, ISymbol callSymbol, IDataFlowNode node) { if (!node.MethodSummaryCache.ContainsKey(callSymbol)) { node.MethodSummaryCache.Add(callSymbol, new HashSet <MethodSummary>()); } node.MethodSummaryCache[callSymbol].Add(calleeSummary); }
/// <summary> /// Constructor. /// </summary> /// <param name="cfg">ControlFlowGraph</param> /// <param name="summary">MethodSummary</param> protected ControlFlowNode(IGraph <IControlFlowNode> cfg, MethodSummary summary) { this.Id = cfg.Nodes.Count; this.Graph = cfg; this.Summary = summary; this.Statements = new List <Statement>(); this.ISuccessors = new HashSet <IControlFlowNode>(); this.IPredecessors = new HashSet <IControlFlowNode>(); cfg.Nodes.Add(this); }
/// <summary> /// Constructor. /// </summary> /// <param name="summary">MethodSummary</param> internal MethodSideEffectsInfo(MethodSummary summary) { this.Summary = summary; this.FieldFlowParamIndexes = new Dictionary<IFieldSymbol, ISet<int>>(); this.FieldAccesses = new Dictionary<IFieldSymbol, ISet<Statement>>(); this.ParameterAccesses = new Dictionary<int, ISet<Statement>>(); this.ReturnedFields = new HashSet<IFieldSymbol>(); this.ReturnedParameters = new HashSet<int>(); this.ReturnTypes = new HashSet<ITypeSymbol>(); this.GivesUpOwnershipParamIndexes = new HashSet<int>(); }
/// <summary> /// Constructor. /// </summary> /// <param name="summary">MethodSummary</param> internal MethodSideEffectsInfo(MethodSummary summary) { this.Summary = summary; this.FieldFlowParamIndexes = new Dictionary <IFieldSymbol, ISet <int> >(); this.FieldAccesses = new Dictionary <IFieldSymbol, ISet <Statement> >(); this.ParameterAccesses = new Dictionary <int, ISet <Statement> >(); this.ReturnedFields = new HashSet <IFieldSymbol>(); this.ReturnedParameters = new HashSet <int>(); this.ReturnTypes = new HashSet <ITypeSymbol>(); this.GivesUpOwnershipParamIndexes = new HashSet <int>(); }
/// <summary> /// Returns all cached method summaries for the specified call. /// </summary> /// <param name="call">ExpressionSyntax</param> /// <param name="node">IDataFlowNode</param> /// <returns>MethodSummarys</returns> private static ISet <MethodSummary> ResolveMethodSummaries(ExpressionSyntax call, IDataFlowNode node) { var summaries = new HashSet <MethodSummary>(); var invocation = call as InvocationExpressionSyntax; var objCreation = call as ObjectCreationExpressionSyntax; var callSymbol = node.Summary.SemanticModel.GetSymbolInfo(call).Symbol; if (callSymbol == null || (invocation == null && objCreation == null)) { return(summaries); } if (node.MethodSummaryCache.ContainsKey(callSymbol)) { summaries.UnionWith(node.MethodSummaryCache[callSymbol]); } else if (invocation != null) { var parameterTypes = MethodSummaryResolver.GetCandidateParameterTypes( invocation.ArgumentList, node); var candidateCalleeDeclarations = MethodSummaryResolver. ResolveCandidateMethodsAtCallSite(invocation, node); foreach (var candidateCalleeDeclaration in candidateCalleeDeclarations) { var calleeSummary = MethodSummary.Create(node.Summary.AnalysisContext, candidateCalleeDeclaration, parameterTypes); if (calleeSummary != null) { summaries.Add(calleeSummary); } } } else { var parameterTypes = MethodSummaryResolver.GetCandidateParameterTypes( objCreation.ArgumentList, node); var constructor = MethodSummaryResolver.ResolveMethodDeclaration( objCreation, node) as ConstructorDeclarationSyntax; if (constructor != null) { var calleeSummary = MethodSummary.Create(node.Summary.AnalysisContext, constructor, parameterTypes); if (calleeSummary != null) { summaries.Add(calleeSummary); } } } return(summaries); }
/// <summary> /// Creates the summary of the specified method, using the /// specified parameter types. /// </summary> /// <param name="context">AnalysisContext</param> /// <param name="method">BaseMethodDeclarationSyntax</param> /// <param name="parameterTypes">ITypeSymbols</param> /// <returns>MethodSummary</returns> public static MethodSummary Create(AnalysisContext context, BaseMethodDeclarationSyntax method, IDictionary <int, ISet <ITypeSymbol> > parameterTypes) { if (method.Body == null) { return(null); } var summary = new MethodSummary(context, method, parameterTypes); summary.BuildSummary(); summary.AnalyzeSummary(); return(summary); }
/// <summary> /// Constructor. /// </summary> /// <param name="dfg">DataFlowGraph</param> /// <param name="cfgNode">IControlFlowNode</param> /// <param name="summary">MethodSummary</param> internal DataFlowNode(IGraph <IDataFlowNode> dfg, IControlFlowNode cfgNode, MethodSummary summary) { this.Id = dfg.Nodes.Count; this.Graph = dfg; this.ControlFlowNode = cfgNode; this.Summary = summary; this.ISuccessors = new HashSet <IDataFlowNode>(); this.IPredecessors = new HashSet <IDataFlowNode>(); dfg.Nodes.Add(this); this.DataFlowInfo = new DataFlowInfo(this, summary.AnalysisContext); this.MethodSummaryCache = new Dictionary <ISymbol, ISet <MethodSummary> >(); this.GivesUpOwnershipMap = new HashSet <ISymbol>(); }
/// <summary> /// Maps the callee summary to the call symbol. /// </summary> /// <param name="calleeSummary">MethodSummary</param> /// <param name="callSymbol">Symbol</param> /// <param name="node">IDataFlowNode</param> private void MapCalleeSummaryToCallSymbol(MethodSummary calleeSummary, ISymbol callSymbol, IDataFlowNode node) { if (!node.MethodSummaryCache.ContainsKey(callSymbol)) { node.MethodSummaryCache.Add(callSymbol, new HashSet<MethodSummary>()); } node.MethodSummaryCache[callSymbol].Add(calleeSummary); }
/// <summary> /// Creates the summary of the specified method. /// </summary> /// <param name="context">AnalysisContext</param> /// <param name="method">BaseMethodDeclarationSyntax</param> /// <returns>MethodSummary</returns> public static MethodSummary Create(AnalysisContext context, BaseMethodDeclarationSyntax method) { return(MethodSummary.Create(context, method, new Dictionary <int, ISet <ITypeSymbol> >())); }
/// <summary> /// Resolves the side-effects in the call. /// </summary> /// <param name="argumentList">Argument list</param> /// <param name="calleeSummary">Callee MethodSummary</param> /// <param name="node">IDataFlowNode</param> /// <returns>Set of side-effects</returns> private IDictionary<IFieldSymbol, ISet<ISymbol>> ResolveSideEffectsInCall(ArgumentListSyntax argumentList, MethodSummary calleeSummary, IDataFlowNode node) { var sideEffects = new Dictionary<IFieldSymbol, ISet<ISymbol>>(); foreach (var sideEffect in calleeSummary.SideEffectsInfo.FieldFlowParamIndexes) { foreach (var index in sideEffect.Value) { var argExpr = argumentList.Arguments[index].Expression; if (argExpr is IdentifierNameSyntax || argExpr is MemberAccessExpressionSyntax) { var argType = node.Summary.SemanticModel.GetTypeInfo(argExpr).Type; if (this.AnalysisContext.IsTypePassedByValueOrImmutable(argType)) { continue; } IdentifierNameSyntax argIdentifier = this.AnalysisContext.GetRootIdentifier(argExpr); if (!sideEffects.ContainsKey(sideEffect.Key)) { sideEffects.Add(sideEffect.Key, new HashSet<ISymbol>()); } sideEffects[sideEffect.Key].Add(node.Summary.SemanticModel.GetSymbolInfo(argIdentifier).Symbol); } } } return sideEffects; }
/// <summary> /// Creates the summary of the specified method, using the /// specified parameter types. /// </summary> /// <param name="context">AnalysisContext</param> /// <param name="method">BaseMethodDeclarationSyntax</param> /// <param name="parameterTypes">ITypeSymbols</param> /// <returns>MethodSummary</returns> public static MethodSummary Create(AnalysisContext context, BaseMethodDeclarationSyntax method, IDictionary<int, ISet<ITypeSymbol>> parameterTypes) { if (method.Body == null) { return null; } var summary = new MethodSummary(context, method, parameterTypes); summary.BuildSummary(); summary.AnalyzeSummary(); return summary; }
/// <summary> /// Constructor. /// </summary> /// <param name="summary">MethodSummary</param> internal ControlFlowGraph(MethodSummary summary) : base() { base.EntryNode = ControlFlowNode.Create(this, summary); base.MergeEmptyNodes(); }