/// <summary> /// Resolves the side-effects in the call. /// </summary> private void ResolveSideEffectsInCall(ExpressionSyntax call, MethodSummary calleeSummary, IDataFlowNode node) { var invocation = call as InvocationExpressionSyntax; var objCreation = call as ObjectCreationExpressionSyntax; if (calleeSummary is null || (invocation is null && objCreation is 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); 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 = 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> /// Initializes the data-flow of the input parameters. /// </summary> 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); DataFlowInfo.AssignTypesToDefinition(node.Summary.ParameterTypes[parameter], definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }
/// <summary> /// Analyzes the data-flow of the binary expression. /// </summary> private void AnalyzeBinaryExpression(ExpressionSyntax expr, IDataFlowNode node) { this.ResolveSideEffectsInExpression(expr, node); var identifier = 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); DataFlowInfo.AssignTypeToDefinition(type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }
/// <summary> /// Creates a new object that is a copy of the current instance. /// </summary> internal DataFlowInfo Clone() { var newInfo = new DataFlowInfo(this.DataFlowNode, this.AnalysisContext); newInfo.GeneratedDefinitions.UnionWith(this.GeneratedDefinitions); newInfo.KilledDefinitions.UnionWith(this.KilledDefinitions); newInfo.InputDefinitions.UnionWith(this.InputDefinitions); newInfo.OutputDefinitions.UnionWith(this.OutputDefinitions); foreach (var pair in this.TaintedDefinitions) { newInfo.TaintedDefinitions.Add(pair.Key, new HashSet <SymbolDefinition>(pair.Value)); } return(newInfo); }
/// <summary> /// Compare with the specified data-flow information. /// </summary> private bool Compare(DataFlowInfo oldInfo, DataFlowInfo newInfo) { if (!oldInfo.GeneratedDefinitions.SetEquals(newInfo.GeneratedDefinitions) || !oldInfo.KilledDefinitions.SetEquals(newInfo.KilledDefinitions) || !oldInfo.InputDefinitions.SetEquals(newInfo.InputDefinitions) || !oldInfo.OutputDefinitions.SetEquals(newInfo.OutputDefinitions) || !oldInfo.TaintedDefinitions.Keys.SequenceEqual(newInfo.TaintedDefinitions.Keys)) { return(false); } foreach (var symbol in oldInfo.TaintedDefinitions) { if (!symbol.Value.SetEquals(newInfo.TaintedDefinitions[symbol.Key])) { return(false); } } return(true); }
/// <summary> /// Initializes the data-flow of field and properties. /// </summary> 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); 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); DataFlowInfo.AssignTypeToDefinition(propertySymbol.Type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); } }