/// <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> /// 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> /// 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); } }