Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSharpObjectInitializationTracker: Add support for tuples and assignment and declaration in the same deconstruction part 2 #5841

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,13 @@ private bool IsLaterAssignedWithAllowedValue(IObjectCreation objectCreation, Sem
.OfType<AssignmentExpressionSyntax>()
.Any(TrackedPropertySetWithAllowedValue);

bool TrackedPropertySetWithAllowedValue(AssignmentExpressionSyntax assignment) =>
variableSymbol.Equals(GetAssignedVariableSymbol(assignment, semanticModel))
&& IsTrackedPropertyName(assignment.Left)
&& IsAllowedValue(assignment.Right, semanticModel);
bool TrackedPropertySetWithAllowedValue(AssignmentExpressionSyntax assignment)
{
var assignmentMap = assignment.MapAssignmentArguments();
return assignmentMap.Any(x => IsTrackedPropertyName(x.Left)
&& variableSymbol.Equals(GetAssignedVariableSymbol(x.Left, semanticModel))
&& IsAllowedValue(x.Right, semanticModel));
}
}

private static IEnumerable<ExpressionSyntax> GetInitializerExpressions(InitializerExpressionSyntax initializer) =>
Expand All @@ -233,12 +236,10 @@ private static ISymbol GetAssignedVariableSymbol(IObjectCreation objectCreation,
: null;
}

private static ISymbol GetAssignedVariableSymbol(AssignmentExpressionSyntax assignment, SemanticModel semanticModel)
private static ISymbol GetAssignedVariableSymbol(SyntaxNode node, SemanticModel semanticModel)
{
var identifier = (assignment.Left as MemberAccessExpressionSyntax)?.Expression ?? assignment.Left as IdentifierNameSyntax;
return identifier != null
? semanticModel.GetSymbolInfo(identifier).Symbol
: null;
var identifier = node is MemberAccessExpressionSyntax memberAccess ? memberAccess.Expression : node as IdentifierNameSyntax;
return semanticModel.GetSymbolInfo(identifier).Symbol;
}

private static IEnumerable<StatementSyntax> GetNextStatements(StatementSyntax statement) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ public void Method()
{
new TelnetRecordStruct(); // Noncompliant {{Using telnet protocol is insecure. Use ssh instead.}}
}

public void SetValueAfterObjectInitialization()
{
var propertyTrue = new SmtpClient("host", 25); // Compliant, property is set below
(propertyTrue.EnableSsl, var x1) = (true, 0);

var propertyFalse = new SmtpClient("host", 25); // Noncompliant
(propertyFalse.EnableSsl, var x2) = (false, 0);
}
}

public record struct TelnetRecordStruct { }
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@
(c.HttpOnly, var x1) = (false, 0); // Noncompliant
(c.HttpOnly, var x2) = (true, 0);
(c.HttpOnly, var x3) = ((false), 0); // Noncompliant

public record struct RecordStruct
{
public void SetValueAfterObjectInitialization()
{
var propertyTrue = new CookieOptions() { HttpOnly = false }; // Compliant, property is set below
(propertyTrue.HttpOnly, var x1) = (true, 0);

var propertyFalse = new CookieOptions() { HttpOnly = false }; // Noncompliant
(propertyFalse.HttpOnly, var x2) = (false, 0); // Noncompliant
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@
(c.Secure, var x1) = (false, 0); // Noncompliant
(c.Secure, var x2) = (true, 0);
(c.Secure, var x3) = ((false), 0); // Noncompliant

public record struct RecordStruct
{
public void SetValueAfterObjectInitialization()
{
var propertyTrue = new CookieOptions() { Secure = false }; // Compliant, property is set below
(propertyTrue.Secure, var x1) = (true, 0);

var propertyFalse = new CookieOptions() { Secure = false }; // Noncompliant
(propertyFalse.Secure, var x2) = (false, 0); // Noncompliant
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@
using System.DirectoryServices;

DirectoryEntry entry1 = new("path", "user", "pass", AuthenticationTypes.Secure);
DirectoryEntry entry2 = new("path", "user", "pass", AuthenticationTypes.None); // Noncompliant
DirectoryEntry entry2 = new("path", "user", "pass", AuthenticationTypes.None); // Noncompliant FP

(entry1.AuthenticationType, var x1) = (AuthenticationTypes.None, 0); // Noncompliant
(entry2.AuthenticationType, var x2) = (AuthenticationTypes.Secure, 0);
(entry2.AuthenticationType, var x3) = ((AuthenticationTypes.None), 0); // Noncompliant

public record struct RecordStruct
{
public void SetValueAfterObjectInitialization()
{
DirectoryEntry entry1 = new("path", "user", "pass", AuthenticationTypes.None); // Compliant, property is set below
(entry1.AuthenticationType, var x1) = (AuthenticationTypes.Secure, 0);

DirectoryEntry entry2 = new("path", "user", "pass", AuthenticationTypes.None); // Noncompliant
(entry2.AuthenticationType, var x2) = (AuthenticationTypes.None, 0); // Noncompliant

AuthenticationTypes AuthenticationType;
(AuthenticationType, var x3) = (AuthenticationTypes.None, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@

XmlDocument doc3 = new();
(doc3.XmlResolver, var x3) = ((new XmlPreloadedResolver()), 0); // Noncompliant

public record struct RecordStruct
{
public void SetValueAfterObjectInitialization()
{
XmlDocument doc1 = new() { XmlResolver = new XmlPreloadedResolver() }; // Compliant, property is set below
(doc1.XmlResolver, var x1) = (null, 0);

XmlDocument doc2 = new() { XmlResolver = new XmlPreloadedResolver() }; // Noncompliant
(doc2.XmlResolver, var x2) = (new XmlPreloadedResolver(), 0); // Noncompliant
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,13 @@ void XmlTextReader_NewResolver(XmlNameTable table)
XmlTextReader reader = new("resources/", table);
(reader.XmlResolver, var x) = (new XmlUrlResolver(), 0); // Noncompliant
}

public void SetValueAfterObjectInitialization(XmlNameTable table)
{
XmlTextReader reader1 = new("resources/", table) { XmlResolver = new XmlUrlResolver() }; // Compliant, property is set below
(reader1.XmlResolver, var x1) = (null, 0);

XmlTextReader reader2 = new("resources/", table) { XmlResolver = new XmlUrlResolver() }; // Noncompliant
(reader2.XmlResolver, var x2) = (new XmlUrlResolver(), 0); // Noncompliant
}
}