Skip to content

Commit 4a3e463

Browse files
authored
Merge pull request #18950 from michaelnebel/csharp/localnotdisposed
C#: Exclude Task from cs/local-not-disposed.
2 parents b3601b1 + 26f0f7f commit 4a3e463

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed

csharp/ql/src/API Abuse/NoDisposeCallOnLocalIDisposable.ql

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import csharp
1717
import Dispose
1818
import semmle.code.csharp.frameworks.System
19+
import semmle.code.csharp.frameworks.system.threading.Tasks
1920
import semmle.code.csharp.commons.Disposal
2021

2122
private class ReturnNode extends DataFlow::ExprNode {
@@ -24,15 +25,27 @@ private class ReturnNode extends DataFlow::ExprNode {
2425
}
2526
}
2627

28+
private class Task extends Type {
29+
Task() {
30+
this instanceof SystemThreadingTasksTaskClass or
31+
this instanceof SystemThreadingTasksTaskTClass
32+
}
33+
}
34+
2735
module DisposeCallOnLocalIDisposableConfig implements DataFlow::ConfigSig {
2836
predicate isSource(DataFlow::Node node) {
29-
node.asExpr() =
30-
any(LocalScopeDisposableCreation disposable |
31-
// Only care about library types - user types often have spurious IDisposable declarations
32-
disposable.getType().fromLibrary() and
33-
// WebControls are usually disposed automatically
34-
not disposable.getType() instanceof WebControl
35-
)
37+
exists(LocalScopeDisposableCreation disposable, Type t |
38+
node.asExpr() = disposable and
39+
t = disposable.getType()
40+
|
41+
// Only care about library types - user types often have spurious IDisposable declarations
42+
t.fromLibrary() and
43+
// WebControls are usually disposed automatically
44+
not t instanceof WebControl and
45+
// It is typically not nessesary to dispose tasks
46+
// https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/
47+
not t instanceof Task
48+
)
3649
}
3750

3851
predicate isSink(DataFlow::Node node) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `cs/local-not-disposed` query no longer flags un-disposed tasks as this is often not needed (explained [here](https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/)).

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO.Compression;
55
using System.Xml;
66
using System.Threading;
7+
using System.Threading.Tasks;
78

89
class Test
910
{
@@ -86,6 +87,13 @@ public IDisposable Method()
8687
using (XmlReader.Create(source ?? new StringReader("xml"), null))
8788
;
8889

90+
// GOOD: Flagging these generates too much noise and there is a general
91+
// acceptance that Tasks are not disposed.
92+
// https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/
93+
Task t = new Task(() => { });
94+
t.Start();
95+
t.Wait();
96+
8997
return null;
9098
}
9199

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
| NoDisposeCallOnLocalIDisposable.cs:50:19:50:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
2-
| NoDisposeCallOnLocalIDisposable.cs:51:18:51:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
3-
| NoDisposeCallOnLocalIDisposable.cs:52:9:52:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
4-
| NoDisposeCallOnLocalIDisposable.cs:74:25:74:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
5-
| NoDisposeCallOnLocalIDisposable.cs:74:42:74:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
6-
| NoDisposeCallOnLocalIDisposable.cs:79:38:79:67 | object creation of type StreamWriter | Disposable 'StreamWriter' is created but not disposed. |
1+
| NoDisposeCallOnLocalIDisposable.cs:51:19:51:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
2+
| NoDisposeCallOnLocalIDisposable.cs:52:18:52:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
3+
| NoDisposeCallOnLocalIDisposable.cs:53:9:53:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
4+
| NoDisposeCallOnLocalIDisposable.cs:75:25:75:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
5+
| NoDisposeCallOnLocalIDisposable.cs:75:42:75:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
6+
| NoDisposeCallOnLocalIDisposable.cs:80:38:80:67 | object creation of type StreamWriter | Disposable 'StreamWriter' is created but not disposed. |
77
| NoDisposeCallOnLocalIDisposableBad.cs:8:22:8:56 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |

0 commit comments

Comments
 (0)