/// <summary> /// Taints the specified definition. /// </summary> /// <param name="taintDefinitions">SymbolDefinitions</param> /// <param name="definition">SymbolDefinition</param> internal void TaintDefinition(IEnumerable <SymbolDefinition> taintDefinitions, SymbolDefinition definition) { if (!this.TaintedDefinitions.ContainsKey(definition)) { this.TaintedDefinitions.Add(definition, new HashSet <SymbolDefinition>()); } this.TaintedDefinitions[definition].UnionWith(taintDefinitions); }
/// <summary> /// Initializes the data-flow of the input parameters. /// </summary> /// <param name="node">IDataFlowNode</param> private void InitializeParameters(IDataFlowNode node) { for (int idx = 0; idx < node.Summary.Method.ParameterList.Parameters.Count; idx++) { var parameter = node.Summary.Method.ParameterList.Parameters[idx]; IParameterSymbol paramSymbol = this.SemanticModel.GetDeclaredSymbol(parameter); SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(paramSymbol); node.DataFlowInfo.AssignTypesToDefinition(node.Summary.ParameterTypes[parameter], definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }
/// <summary> /// Generates a new definition for the specified symbol. /// </summary> /// <param name="symbol">ISymbol</param> /// <returns>SymbolDefinition</returns> internal SymbolDefinition GenerateDefinition(ISymbol symbol) { var definition = this.GeneratedDefinitions.FirstOrDefault(def => def.Symbol.Equals(symbol)); if (definition == null) { definition = new SymbolDefinition(symbol, this.DataFlowNode); this.GeneratedDefinitions.Add(definition); } return(definition); }
/// <summary> /// Analyzes the data-flow of the binary expression. /// </summary> /// <param name="expr">ExpressionSyntax</param> /// <param name="node">IDataFlowNode</param> private void AnalyzeBinaryExpression(ExpressionSyntax expr, IDataFlowNode node) { this.ResolveSideEffectsInExpression(expr, node); var identifier = this.AnalysisContext.GetIdentifier(expr); ISymbol symbol = this.SemanticModel.GetSymbolInfo(expr).Symbol; ITypeSymbol type = this.SemanticModel.GetTypeInfo(expr).Type; if (node.DataFlowInfo.IsFreshSymbol(symbol)) { SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(symbol); node.DataFlowInfo.AssignTypeToDefinition(type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }
/// <summary> /// Checks if the specified definition is alive in some /// path between the two specified nodes. /// </summary> /// <param name="definition">SymbolDefinition</param> /// <param name="fromNode">IDataFlowNode</param> /// <param name="toNode">IDataFlowNode</param> /// <returns>Boolean</returns> private bool IsDefinitionReachingNodeInCycle(SymbolDefinition definition, IDataFlowNode fromNode, IDataFlowNode toNode) { var queue = new Queue <IList <IDataFlowNode> >(); queue.Enqueue(new List <IDataFlowNode> { fromNode }); while (queue.Count > 0) { var path = queue.Dequeue(); var node = path.Last(); if (node.Equals(toNode) && path.Count > 1) { bool isAlive = true; foreach (var visitedNode in path) { var generatedDefinition = visitedNode.DataFlowInfo. GetGeneratedDefinitionOfSymbol(definition.Symbol); if (generatedDefinition != null && generatedDefinition.Equals(definition)) { isAlive = false; break; } } if (isAlive) { return(true); } } foreach (var successor in node.ISuccessors.Where( n => !path.Skip(1).Contains(n))) { var nextPath = new List <IDataFlowNode>(path); nextPath.Add(successor); queue.Enqueue(nextPath); } } return(false); }
/// <summary> /// Resolves the direct aliases of the specified definition. /// </summary> /// <param name="definition">SymbolDefinition</param> /// <returns>SymbolDefinitions</returns> private ISet <SymbolDefinition> ResolveDirectAliases(SymbolDefinition definition) { var aliasDefinitions = new HashSet <SymbolDefinition>(); foreach (var pair in this.TaintedDefinitions) { if (pair.Key.Equals(definition)) { aliasDefinitions.UnionWith(pair.Value); } if (pair.Value.Contains(definition)) { aliasDefinitions.Add(pair.Key); } } return(aliasDefinitions); }
/// <summary> /// Initializes the data-flow of field and properties. /// </summary> /// <param name="node">IDataFlowNode</param> private void InitializeFieldsAndProperties(IDataFlowNode node) { var symbols = this.Summary.Method.DescendantNodes(n => true). OfType <IdentifierNameSyntax>().Select(id => this.SemanticModel. GetSymbolInfo(id).Symbol).Where(s => s != null).Distinct(); var fieldSymbols = symbols.Where(val => val.Kind == SymbolKind.Field); foreach (var fieldSymbol in fieldSymbols.Select(s => s as IFieldSymbol)) { SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(fieldSymbol); node.DataFlowInfo.AssignTypeToDefinition(fieldSymbol.Type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); } var propertySymbols = symbols.Where(val => val.Kind == SymbolKind.Property); foreach (var propertySymbol in propertySymbols.Select(s => s as IPropertySymbol)) { SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(propertySymbol); node.DataFlowInfo.AssignTypeToDefinition(propertySymbol.Type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }
/// <summary> /// Resolves the direct aliases of the specified definition. /// </summary> /// <param name="definition">SymbolDefinition</param> /// <returns>SymbolDefinitions</returns> private ISet<SymbolDefinition> ResolveDirectAliases(SymbolDefinition definition) { var aliasDefinitions = new HashSet<SymbolDefinition>(); foreach (var pair in this.TaintedDefinitions) { if (pair.Key.Equals(definition)) { aliasDefinitions.UnionWith(pair.Value); } if (pair.Value.Contains(definition)) { aliasDefinitions.Add(pair.Key); } } return aliasDefinitions; }
/// <summary> /// Taints the specified definition. /// </summary> /// <param name="taintDefinitions">SymbolDefinitions</param> /// <param name="definition">SymbolDefinition</param> internal void TaintDefinition(IEnumerable<SymbolDefinition> taintDefinitions, SymbolDefinition definition) { if (!this.TaintedDefinitions.ContainsKey(definition)) { this.TaintedDefinitions.Add(definition, new HashSet<SymbolDefinition>()); } this.TaintedDefinitions[definition].UnionWith(taintDefinitions); }
/// <summary> /// Taints the specified definition. /// </summary> /// <param name="taintDefinition">SymbolDefinition</param> /// <param name="definition">SymbolDefinition</param> internal void TaintDefinition(SymbolDefinition taintDefinition, SymbolDefinition definition) { this.TaintDefinition(new HashSet<SymbolDefinition> { taintDefinition }, definition); }
/// <summary> /// Generates a new definition for the specified symbol. /// </summary> /// <param name="symbol">ISymbol</param> /// <returns>SymbolDefinition</returns> internal SymbolDefinition GenerateDefinition(ISymbol symbol) { var definition = this.GeneratedDefinitions.FirstOrDefault(def => def.Symbol.Equals(symbol)); if (definition == null) { definition = new SymbolDefinition(symbol, this.DataFlowNode); this.GeneratedDefinitions.Add(definition); } return definition; }
/// <summary> /// Assigns the specified type to the definition. /// </summary> /// <param name="type">ITypeSymbol</param> /// <param name="definition">SymbolDefinition</param> internal void AssignTypeToDefinition(ITypeSymbol type, SymbolDefinition definition) { if (type != null) { definition.CandidateTypes.Clear(); definition.CandidateTypes.Add(type); } }
/// <summary> /// Assigns the specified types to the definition. /// </summary> /// <param name="types">ITypeSymbols</param> /// <param name="definition">SymbolDefinition</param> internal void AssignTypesToDefinition(ISet<ITypeSymbol> types, SymbolDefinition definition) { if (types.Count > 0 && !types.Any(type => type == null)) { definition.CandidateTypes.Clear(); definition.CandidateTypes.UnionWith(types); } }
/// <summary> /// Taints the specified definition. /// </summary> /// <param name="taintDefinition">SymbolDefinition</param> /// <param name="definition">SymbolDefinition</param> internal void TaintDefinition(SymbolDefinition taintDefinition, SymbolDefinition definition) { this.TaintDefinition(new HashSet <SymbolDefinition> { taintDefinition }, definition); }