-
Notifications
You must be signed in to change notification settings - Fork 222
/
CertificateValidationCheck.cs
109 lines (93 loc) · 5.65 KB
/
CertificateValidationCheck.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2023 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
namespace SonarAnalyzer.Rules.CSharp
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class CertificateValidationCheck : CertificateValidationCheckBase<
SyntaxKind,
ArgumentSyntax,
ExpressionSyntax,
IdentifierNameSyntax,
AssignmentExpressionSyntax,
InvocationExpressionSyntax,
ParameterSyntax,
VariableDeclaratorSyntax,
ParenthesizedLambdaExpressionSyntax,
MemberAccessExpressionSyntax>
{
protected override ILanguageFacade<SyntaxKind> Language { get; } = CSharpFacade.Instance;
protected override SyntaxKind[] MethodDeclarationKinds { get; } = { SyntaxKind.MethodDeclaration, SyntaxKindEx.LocalFunctionStatement };
internal override MethodParameterLookupBase<ArgumentSyntax> CreateParameterLookup(SyntaxNode argumentListNode, IMethodSymbol method) =>
argumentListNode switch
{
InvocationExpressionSyntax invocation => new CSharpMethodParameterLookup(invocation.ArgumentList, method),
_ when ObjectCreationFactory.TryCreate(argumentListNode) is { ArgumentList: { } argumentList } => new CSharpMethodParameterLookup(argumentList, method),
_ => throw new ArgumentException("Unexpected type.", nameof(argumentListNode)) // This should be throw only by bad usage of this method, not by input dependency
};
protected override void Initialize(SonarAnalysisContext context)
{
// Handling of += syntax
context.RegisterNodeAction(CheckAssignmentSyntax, SyntaxKind.AddAssignmentExpression);
// Handling of = syntax
context.RegisterNodeAction(CheckAssignmentSyntax, SyntaxKind.SimpleAssignmentExpression);
// Handling of constructor parameter syntax (SslStream)
context.RegisterNodeAction(CheckConstructorParameterSyntax, SyntaxKind.ObjectCreationExpression, SyntaxKindEx.ImplicitObjectCreationExpression);
}
protected override SyntaxNode FindRootTypeDeclaration(SyntaxNode node) =>
base.FindRootTypeDeclaration(node) ?? node.FirstAncestorOrSelf<GlobalStatementSyntax>()?.Parent;
protected override Location ExpressionLocation(SyntaxNode expression) =>
// For Lambda expression extract location of the parentheses only to separate them from secondary location of "true"
((expression is ParenthesizedLambdaExpressionSyntax lambda) ? lambda.ParameterList : expression).GetLocation();
protected override void SplitAssignment(AssignmentExpressionSyntax assignment, out IdentifierNameSyntax leftIdentifier, out ExpressionSyntax right)
{
leftIdentifier = assignment.Left.DescendantNodesAndSelf().OfType<IdentifierNameSyntax>().LastOrDefault();
right = assignment.Right;
}
protected override IEqualityComparer<ExpressionSyntax> CreateNodeEqualityComparer() =>
new CSharpSyntaxNodeEqualityComparer<ExpressionSyntax>();
protected override ExpressionSyntax[] FindReturnAndThrowExpressions(InspectionContext c, SyntaxNode block) =>
block.DescendantNodes().OfType<ReturnStatementSyntax>().Select(x => x.Expression)
// Throw statements #2825. x.Expression can be NULL for standalone Throw and we need that one as well.
.Concat(block.DescendantNodes().OfType<ThrowStatementSyntax>().Select(x => x.Expression))
.ToArray();
protected override bool IsTrueLiteral(ExpressionSyntax expression) =>
expression?.RemoveParentheses().Kind() == SyntaxKind.TrueLiteralExpression;
protected override ExpressionSyntax VariableInitializer(VariableDeclaratorSyntax variable) =>
variable.Initializer?.Value;
protected override ImmutableArray<Location> LambdaLocations(InspectionContext c, ParenthesizedLambdaExpressionSyntax lambda)
{
if (lambda.Body is BlockSyntax block)
{
return BlockLocations(c, block);
}
if (lambda.Body is ExpressionSyntax expr && IsTrueLiteral(expr)) // LiteralExpressionSyntax or ParenthesizedExpressionSyntax like (((true)))
{
return new[] { lambda.Body.GetLocation() }.ToImmutableArray(); // Code was found guilty for lambda (...) => true
}
return ImmutableArray<Location>.Empty;
}
protected override SyntaxNode LocalVariableScope(VariableDeclaratorSyntax variable) =>
variable.FirstAncestorOrSelf<BlockSyntax>();
protected override SyntaxNode ExtractArgumentExpressionNode(SyntaxNode expression) =>
expression.RemoveParentheses();
protected override SyntaxNode SyntaxFromReference(SyntaxReference reference) =>
reference.GetSyntax(); // VB.NET has more complicated logic
}
}