Skip to content

Commit f408a6d

Browse files
authored
Merge pull request #1404 from calumgrant/cs/dispose-not-called-on-throw
C#: Improvement to cs/dispose-not-called-on-throw
2 parents 03cf8ef + 0287572 commit f408a6d

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Improvements to C# analysis
2+
3+
## Changes to existing queries
4+
5+
| **Query** | **Expected impact** | **Change** |
6+
|------------------------------|------------------------|-----------------------------------|
7+
| 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. |
8+
9+
## Changes to code extraction
10+
11+
## Changes to QL libraries
12+
13+
## Changes to autobuilder

csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,19 @@ private class DisposeCall extends MethodCall {
5252
DisposeCall() { this.getTarget() instanceof DisposeMethod }
5353
}
5454

55+
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
56+
DataFlow::localFlowStep(nodeFrom, nodeTo) and
57+
not exists(AssignableDefinition def, UsingStmt us |
58+
nodeTo.asExpr() = def.getAReachableRead() and
59+
def.getTargetAccess() = us.getAVariableDeclExpr().getAccess()
60+
)
61+
}
62+
5563
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
56-
DataFlow::localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
64+
localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
5765
or
5866
exists(DataFlow::Node mid | reachesDisposeCall(disposeCall, mid) |
59-
DataFlow::localFlowStep(node, mid)
67+
localFlowStep(node, mid)
6068
)
6169
}
6270

csharp/ql/test/query-tests/API Abuse/DisposeNotCalledOnException/DisposeNotCalledOnException.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ public void Method()
6262
// GOOD: using declaration
6363
using SqlConnection c2 = new SqlConnection("");
6464
c2.Open();
65+
66+
// GOOD: Always disposed
67+
using SqlConnection c3 = new SqlConnection("");
68+
Throw2(c3);
69+
c3.Dispose();
70+
71+
// GOOD: Disposed automatically
72+
using (SqlConnection c4 = new SqlConnection(""))
73+
{
74+
Throw2(c4);
75+
c4.Dispose();
76+
}
6577
}
6678

6779
void Throw1(SqlConnection sc)

0 commit comments

Comments
 (0)