/// <summary> /// Checks and Reports if Order is Invalid /// </summary> /// <param name="validEvents"></param> /// <param name="containingMethod"></param> public bool IsValidOrder(ValidEvents validEvents, string containingMethod, List <KeyValuePair <string, string> > eventsOrderDict, List <string> eventOrderContraint) { if (validEvents.IsValidEvent) { foreach (var events in validEvents.ValidEventsDict) { var analyzedEvents = eventsOrderDict.Select(x => x).Where(y => y.Key.Equals(validEvents.AggregatorName)).Select(x => x.Value); if (analyzedEvents.Count() != 0) { if (analyzedEvents.FirstOrDefault().Equals(containingMethod)) { var currentEventsOrder = eventsOrderDict.Select(x => x.Key).ToList(); var commonUtilities = serviceProvider.GetService <ICommonUtilities>(); Regex regex = commonUtilities.ListToRegex(eventOrderContraint); bool valid = regex.IsMatch(string.Join(delimiter, currentEventsOrder)) ? true : false; if (!valid) { return(false); } } } else { KeyValuePair <string, string> eventsToAdd = new KeyValuePair <string, string>(validEvents.AggregatorName, containingMethod); eventsOrderDict.AddRange(Enumerable.Repeat(eventsToAdd, events.Value.Count)); } } } return(true); }
public ValidEvents AnalyzeAssignmentExprSyntax(IEnumerable <CryptoSignature> cryptoMethods, CryslJsonModel cryslModel, SyntaxNodeAnalysisContext context, ISymbol leftExprSymbol) { ValidEvents validEvents = new ValidEvents(); MethodSignatureModel methodSignatureModel = new MethodSignatureModel { MethodName = leftExprSymbol.Name.ToString() }; List <MethodSignatureModel> methodSignatureModelsList = new List <MethodSignatureModel>(); methodSignatureModelsList.Add(methodSignatureModel); //Iterate through all the satisfied crypto signatures foreach (var cryptoMethod in cryptoMethods) { Dictionary <string, List <MethodSignatureModel> > validEventsDict = new Dictionary <string, List <MethodSignatureModel> >(); validEventsDict.Add(cryptoMethod.Event_Var_Name, methodSignatureModelsList); validEvents.IsValidEvent = true; validEvents.AggregatorName = cryptoMethod.Event_Var_Name; validEvents.ValidEventsDict = validEventsDict; if (cryptoMethod.Is_property) { validEvents.IsProperty = true; validEvents.PropertyName = cryptoMethod.Object_variable; } } return(validEvents); }
/// <summary> /// Analyze thr MemberAcessExpressionSyntax Nodes /// </summary> /// <param name="memberAccessExpressions"></param> /// <param name="cryslData"></param> /// <param name="context"></param> /// <returns></returns> public ValidEvents AnalyzeMemAccessExprSyntax(IdentifierNameSyntax identifier, IEnumerable <CryptoSignature> cryptoMethods, Methods methods, CryslJsonModel cryslData, SyntaxNodeAnalysisContext context, IMethodSymbol identifierSymbolInfo, TextSpan nodeSPan) { ValidEvents validEvents = new ValidEvents(); // Check for valid event only if Identifier is of Spec type in Crysl. if (identifierSymbolInfo.ReturnType.ToString().Equals(cryslData.Spec_Section.Class_Name)) { List <MethodSignatureModel> methodSignatureModelsList = new List <MethodSignatureModel>(); foreach (var method in cryptoMethods) { ICommonUtilities commonUtilities = serviceProvider.GetService <ICommonUtilities>(); //Check if the Event is Valid bool isValidEvent = commonUtilities.IsMethodInEvents(method, identifierSymbolInfo, cryslData.Object_Section.Objects_Declaration); if (isValidEvent) { MethodSignatureModel currentValidEvent = new MethodSignatureModel { MethodName = identifierSymbolInfo.Name, Parameters = method.Argument_types, }; methodSignatureModelsList.Add(currentValidEvent); //Go to the Containing Method Declaration Node var containingMethodDeclarationNode = identifier.FirstAncestorOrSelf <MethodDeclarationSyntax>(); var invExprSyntaxWalker = new InvocationExpressionSyntaxWalker(cryslData, context, nodeSPan); //Walk through the current method to find all invocations of the given type invExprSyntaxWalker.Visit(containingMethodDeclarationNode); Dictionary <string, List <MethodSignatureModel> > validEventsDict = invExprSyntaxWalker.GetMethodsList(); if (!validEventsDict.ContainsKey(method.Event_Var_Name)) { validEventsDict.Add(method.Event_Var_Name, methodSignatureModelsList); } //If there are two events of same type else if (validEventsDict.ContainsKey(method.Event_Var_Name)) { foreach (var methodSig in validEventsDict.Values) { methodSignatureModelsList.AddRange(methodSig); } validEventsDict[method.Event_Var_Name] = methodSignatureModelsList; } //Check if the Aggregator Condition Satisfies bool isAggregatorCondition = commonUtilities.CheckAggregator(validEventsDict, methods.Aggregator.Aggregators); if (isAggregatorCondition) { validEvents.IsValidEvent = true; validEvents.ValidEventsDict = validEventsDict; validEvents.AggregatorName = methods.Aggregator.Aggregator_Name; } else { validEvents.IsValidEvent = false; } return(validEvents); } } } validEvents.IsValidEvent = false; return(validEvents); }
/// <summary> /// Check if Property Constraints are Satified /// </summary> /// <param name="cryslModel"></param> /// <param name="validEvents"></param> /// <param name="rightExprValue"></param> /// <returns></returns> public bool IsPropertyConstraintSatisfied(CryslJsonModel cryslModel, ValidEvents validEvents, string rightExprValue) { var constraintsList = cryslModel.Constraints_Section.Constraints.Select(x => x).Where(y => y.Object_Varname.ToString().Equals(validEvents.PropertyName)).Select(x => x.Constraints_List); if (constraintsList.Count() > 0) { bool isPrimaryConstraintSatisfied = false; foreach (var constraints in constraintsList) { foreach (var constraint in constraints) { if (constraint.ToString().Equals(rightExprValue.ToString())) { isPrimaryConstraintSatisfied = true; } } if (!isPrimaryConstraintSatisfied) { return(false); } } } return(true); }
/// <summary> /// Check if the Additional Constraints are Satisfied /// </summary> /// <param name="additionalConstraints"></param> /// <param name="localInvocatorSymbolInfo"></param> /// <param name="leftExprSymbolInfo"></param> /// <param name="rightExprSymbolInfo"></param> /// <param name="objectsDeclarations"></param> /// <returns></returns> public bool IsAdditionalConstraintSatisfied(AddConstraints additionalConstraints, ISymbol leftExprSymbolInfo, string rightExprValue, ICollection <ObjectsDeclaration> objectsDeclarations, ValidEvents validEvents) { bool isAdditionalConstraintSatisfied = true; foreach (var constraints in additionalConstraints.ConstraintsModels) { //Iterate through each additional constraints foreach (var constraint in constraints.AdditionalConstraints) { if (leftExprSymbolInfo.Kind.Equals(SymbolKind.Property)) { IPropertySymbol leftExprPropertyInfo = (IPropertySymbol)leftExprSymbolInfo; var objectTypes = objectsDeclarations.Select(x => x).Where(y => y.Object_type.ToString().Equals(leftExprPropertyInfo.Type.ToString()) && y.Var_name.ToString().Equals(validEvents.PropertyName)); // Iterate through all the matched object declarations foreach (var objectType in objectTypes) { if (constraint.Object_Varname_Additional_Constraint.ToString().Equals(objectType.Var_name.ToString())) { bool isAddConstraintSatisfied = false; foreach (var addConstraint in constraint.Additional_Constraints_List) { //The Right Expression Node Value Should be according to the value in the Constraint if (addConstraint.ToString().Equals(rightExprValue)) { isAddConstraintSatisfied = true; } } if (!isAddConstraintSatisfied) { isAdditionalConstraintSatisfied = false; return(isAdditionalConstraintSatisfied); } } } } } } return(isAdditionalConstraintSatisfied); }
/// <summary> /// Analyze Method Invocation Nodes /// </summary> /// <param name="context"></param> private static void AnalyzeMethodInvocationNode(SyntaxNodeAnalysisContext context) { var diagnostics = context.Compilation.GetDiagnostics(); var invocationExpressionNode = context.Node; var memAcessExprNode = invocationExpressionNode.ChildNodes().OfType <MemberAccessExpressionSyntax>(); var argumentsList = invocationExpressionNode.ChildNodes().OfType <ArgumentListSyntax>(); foreach (var node in memAcessExprNode) { var identifierNode = node.ChildNodes().OfType <IdentifierNameSyntax>(); foreach (var identifier in identifierNode) { var result = _cryslSpecificationModel.Event_Section.Methods.Select(x => x.Crypto_Signature .Where(y => y.Method_Name.ToString().Equals(identifier.Identifier.Value.ToString()))); foreach (var methods in _cryslSpecificationModel.Event_Section.Methods) { // Check if method signature matches with the method signature defined in events section of the Crysl. var cryptoMethods = methods.Crypto_Signature.Select(y => y).Where(x => x.Method_Name.ToString().Equals(identifier.Identifier.Value.ToString())); if (cryptoMethods.Count() > 0) { IEventSectionAnalyzer analyzer = serviceProvider.GetService <IEventSectionAnalyzer>(); var identifierSymbolInfo = (IMethodSymbol)context.SemanticModel.GetSymbolInfo(identifier).Symbol; //Check for Valid Events ValidEvents validEvents = analyzer.AnalyzeMemAccessExprSyntax(identifier, cryptoMethods, methods, _cryslSpecificationModel, context, identifierSymbolInfo, node.Span); //Check for Valid Order IOrderSectionAnalyzer orderSectionAnalyzer = serviceProvider.GetService <IOrderSectionAnalyzer>(); bool isOrderValid = orderSectionAnalyzer.IsValidOrder(validEvents, context.ContainingSymbol.ToString(), EventsOrderDict, EventOrderContraint); //Report If Order Constraint is Violated if (!isOrderValid) { //Report Diagnostics Order Violation } //If Event is Valid then Check Constraints if (validEvents.IsValidEvent) { //Check for Valid Constraints foreach (var parameter in validEvents.ValidEventsDict) { IConstraintsSectionAnalyzer constraintsSectionAnalyzer = serviceProvider.GetService <IConstraintsSectionAnalyzer>(); List <ConstraintsModel> satisfiedConstraintsList = new List <ConstraintsModel>(); foreach (var parameterValue in parameter.Value) { //Check for constraints only if arguments are present if (parameterValue.Parameters.Count != 0) { satisfiedConstraintsList = constraintsSectionAnalyzer.AnalyzeParameters(argumentsList, parameterValue.Parameters, _cryslSpecificationModel.Constraints_Section.Constraints); ReportConstraintsSection(context, satisfiedConstraintsList); AddConstraints additionalConstraints = new AddConstraints { EventKey = parameter.Key, EventVariableDeclarator = identifier.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().First().Identifier.Text, ConstraintsModels = satisfiedConstraintsList }; _additionalConstraintsDict.Add(identifierSymbolInfo.ReturnType.ToString(), additionalConstraints); } } } } else { //Report context to diagnostics as invalid event } } } } } }