mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #1404 from calumgrant/cs/dispose-not-called-on-throw
C#: Improvement to cs/dispose-not-called-on-throw
This commit is contained in:
13
change-notes/1.22/analysis-csharp.md
Normal file
13
change-notes/1.22/analysis-csharp.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Improvements to C# analysis
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|------------------------------|------------------------|-----------------------------------|
|
||||
| Dispose may not be called if an exception is thrown during execution (`cs/dispose-not-called-on-throw`) | Fewer false positive results | Results have been removed where an object is disposed both by a `using` statement and a `Dispose` call. |
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
## Changes to autobuilder
|
||||
@@ -52,11 +52,19 @@ private class DisposeCall extends MethodCall {
|
||||
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
||||
}
|
||||
|
||||
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
DataFlow::localFlowStep(nodeFrom, nodeTo) and
|
||||
not exists(AssignableDefinition def, UsingStmt us |
|
||||
nodeTo.asExpr() = def.getAReachableRead() and
|
||||
def.getTargetAccess() = us.getAVariableDeclExpr().getAccess()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
|
||||
DataFlow::localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
|
||||
localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
|
||||
or
|
||||
exists(DataFlow::Node mid | reachesDisposeCall(disposeCall, mid) |
|
||||
DataFlow::localFlowStep(node, mid)
|
||||
localFlowStep(node, mid)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,18 @@ class Test
|
||||
// GOOD: using declaration
|
||||
using SqlConnection c2 = new SqlConnection("");
|
||||
c2.Open();
|
||||
|
||||
// GOOD: Always disposed
|
||||
using SqlConnection c3 = new SqlConnection("");
|
||||
Throw2(c3);
|
||||
c3.Dispose();
|
||||
|
||||
// GOOD: Disposed automatically
|
||||
using (SqlConnection c4 = new SqlConnection(""))
|
||||
{
|
||||
Throw2(c4);
|
||||
c4.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void Throw1(SqlConnection sc)
|
||||
|
||||
Reference in New Issue
Block a user