mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
C#: Handle async data flow in expression bodied callables
This commit is contained in:
@@ -11,6 +11,7 @@ private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.metrics.Complexity
|
||||
private import TypeRef
|
||||
private import semmle.code.csharp.frameworks.system.threading.Tasks
|
||||
|
||||
/**
|
||||
* An element that can be called.
|
||||
@@ -206,7 +207,11 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
exists(ReturnStmt ret | ret.getEnclosingCallable() = this | e = ret.getExpr())
|
||||
or
|
||||
e = this.getExpressionBody() and
|
||||
not this.getReturnType() instanceof VoidType
|
||||
not this.getReturnType() instanceof VoidType and
|
||||
(
|
||||
not this.(Modifiable).isAsync() or
|
||||
not this.getReturnType() instanceof SystemThreadingTasksTaskClass
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this callable can yield return the expression `e`. */
|
||||
|
||||
@@ -788,7 +788,7 @@ private module Cached {
|
||||
or
|
||||
exists(Expr e |
|
||||
e = node1.asExpr() and
|
||||
node2.(AsyncReturnNode).getReturnStmt().getExpr() = e and
|
||||
node2.(AsyncReturnNode).getExpr() = e and
|
||||
c = getResultContent()
|
||||
)
|
||||
or
|
||||
@@ -1411,23 +1411,23 @@ private module ReturnNodes {
|
||||
*/
|
||||
class AsyncReturnNode extends ReturnNode, NodeImpl, TAsyncReturnNode {
|
||||
private ControlFlow::Nodes::ElementNode cfn;
|
||||
private ReturnStmt rs;
|
||||
private Expr expr;
|
||||
|
||||
AsyncReturnNode() { this = TAsyncReturnNode(cfn) and rs.getExpr().getAControlFlowNode() = cfn }
|
||||
AsyncReturnNode() { this = TAsyncReturnNode(cfn) and expr = cfn.getElement() }
|
||||
|
||||
ReturnStmt getReturnStmt() { result = rs }
|
||||
Expr getExpr() { result = expr }
|
||||
|
||||
override NormalReturnKind getKind() { any() }
|
||||
|
||||
override Callable getEnclosingCallableImpl() { result = rs.getEnclosingCallable() }
|
||||
override Callable getEnclosingCallableImpl() { result = expr.getEnclosingCallable() }
|
||||
|
||||
override Type getTypeImpl() { result = rs.getEnclosingCallable().getReturnType() }
|
||||
override Type getTypeImpl() { result = expr.getEnclosingCallable().getReturnType() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { result = cfn }
|
||||
|
||||
override Location getLocationImpl() { result = rs.getLocation() }
|
||||
override Location getLocationImpl() { result = expr.getLocation() }
|
||||
|
||||
override string toStringImpl() { result = rs.toString() }
|
||||
override string toStringImpl() { result = expr.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ class Test
|
||||
|
||||
public void TestAwait3(string input)
|
||||
{
|
||||
Sink(ReturnAwait(input).Result);
|
||||
Sink(ReturnAwait2(input).Result);
|
||||
}
|
||||
|
||||
private async Task<string> ReturnAwait(string x)
|
||||
@@ -47,4 +47,6 @@ class Test
|
||||
{
|
||||
return Task.FromResult(x);
|
||||
}
|
||||
|
||||
private async Task<string> ReturnAwait2(string x) => x;
|
||||
}
|
||||
@@ -10,19 +10,20 @@ edges
|
||||
| Async.cs:26:17:26:40 | await ... : String | Async.cs:27:14:27:14 | access to local variable x |
|
||||
| Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String | Async.cs:26:17:26:40 | await ... : String |
|
||||
| Async.cs:26:35:26:39 | access to parameter input : String | Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:30:35:30:39 | input : String | Async.cs:32:26:32:30 | access to parameter input : String |
|
||||
| Async.cs:32:14:32:31 | call to method ReturnAwait [Result] : String | Async.cs:32:14:32:38 | access to property Result |
|
||||
| Async.cs:32:26:32:30 | access to parameter input : String | Async.cs:32:14:32:31 | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:30:35:30:39 | input : String | Async.cs:32:27:32:31 | access to parameter input : String |
|
||||
| Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String | Async.cs:32:14:32:39 | access to property Result |
|
||||
| Async.cs:32:27:32:31 | access to parameter input : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String |
|
||||
| Async.cs:35:51:35:51 | x : String | Async.cs:38:16:38:16 | access to parameter x : String |
|
||||
| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:21:20:21:37 | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:32:14:32:31 | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:41:33:41:37 | input : String | Async.cs:43:25:43:29 | access to parameter input : String |
|
||||
| Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String | Async.cs:43:14:43:37 | access to property Result |
|
||||
| Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String |
|
||||
| Async.cs:46:44:46:44 | x : String | Async.cs:48:32:48:32 | access to parameter x : String |
|
||||
| Async.cs:48:16:48:33 | call to method FromResult [Result] : String | Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String |
|
||||
| Async.cs:48:32:48:32 | access to parameter x : String | Async.cs:48:16:48:33 | call to method FromResult [Result] : String |
|
||||
| Async.cs:51:52:51:52 | x : String | Async.cs:51:58:51:58 | access to parameter x : String |
|
||||
| Async.cs:51:58:51:58 | access to parameter x : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String |
|
||||
nodes
|
||||
| Async.cs:9:37:9:41 | input : String | semmle.label | input : String |
|
||||
| Async.cs:11:14:11:26 | call to method Return | semmle.label | call to method Return |
|
||||
@@ -39,9 +40,9 @@ nodes
|
||||
| Async.cs:26:35:26:39 | access to parameter input : String | semmle.label | access to parameter input : String |
|
||||
| Async.cs:27:14:27:14 | access to local variable x | semmle.label | access to local variable x |
|
||||
| Async.cs:30:35:30:39 | input : String | semmle.label | input : String |
|
||||
| Async.cs:32:14:32:31 | call to method ReturnAwait [Result] : String | semmle.label | call to method ReturnAwait [Result] : String |
|
||||
| Async.cs:32:14:32:38 | access to property Result | semmle.label | access to property Result |
|
||||
| Async.cs:32:26:32:30 | access to parameter input : String | semmle.label | access to parameter input : String |
|
||||
| Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String | semmle.label | call to method ReturnAwait2 [Result] : String |
|
||||
| Async.cs:32:14:32:39 | access to property Result | semmle.label | access to property Result |
|
||||
| Async.cs:32:27:32:31 | access to parameter input : String | semmle.label | access to parameter input : String |
|
||||
| Async.cs:35:51:35:51 | x : String | semmle.label | x : String |
|
||||
| Async.cs:38:16:38:16 | access to parameter x : String | semmle.label | access to parameter x : String |
|
||||
| Async.cs:41:33:41:37 | input : String | semmle.label | input : String |
|
||||
@@ -51,6 +52,8 @@ nodes
|
||||
| Async.cs:46:44:46:44 | x : String | semmle.label | x : String |
|
||||
| Async.cs:48:16:48:33 | call to method FromResult [Result] : String | semmle.label | call to method FromResult [Result] : String |
|
||||
| Async.cs:48:32:48:32 | access to parameter x : String | semmle.label | access to parameter x : String |
|
||||
| Async.cs:51:52:51:52 | x : String | semmle.label | x : String |
|
||||
| Async.cs:51:58:51:58 | access to parameter x : String | semmle.label | access to parameter x : String |
|
||||
#select
|
||||
| Async.cs:11:14:11:26 | call to method Return | Async.cs:9:37:9:41 | input : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:9:37:9:41 | input | User-provided value |
|
||||
| Async.cs:11:14:11:26 | call to method Return | Async.cs:14:34:14:34 | x : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:14:34:14:34 | x | User-provided value |
|
||||
@@ -58,7 +61,7 @@ nodes
|
||||
| Async.cs:21:14:21:37 | await ... | Async.cs:35:51:35:51 | x : String | Async.cs:21:14:21:37 | await ... | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value |
|
||||
| Async.cs:27:14:27:14 | access to local variable x | Async.cs:24:41:24:45 | input : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:24:41:24:45 | input | User-provided value |
|
||||
| Async.cs:27:14:27:14 | access to local variable x | Async.cs:35:51:35:51 | x : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value |
|
||||
| Async.cs:32:14:32:38 | access to property Result | Async.cs:30:35:30:39 | input : String | Async.cs:32:14:32:38 | access to property Result | $@ flows to here and is used. | Async.cs:30:35:30:39 | input | User-provided value |
|
||||
| Async.cs:32:14:32:38 | access to property Result | Async.cs:35:51:35:51 | x : String | Async.cs:32:14:32:38 | access to property Result | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value |
|
||||
| Async.cs:32:14:32:39 | access to property Result | Async.cs:30:35:30:39 | input : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:30:35:30:39 | input | User-provided value |
|
||||
| Async.cs:32:14:32:39 | access to property Result | Async.cs:51:52:51:52 | x : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:51:52:51:52 | x | User-provided value |
|
||||
| Async.cs:43:14:43:37 | access to property Result | Async.cs:41:33:41:37 | input : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:41:33:41:37 | input | User-provided value |
|
||||
| Async.cs:43:14:43:37 | access to property Result | Async.cs:46:44:46:44 | x : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:46:44:46:44 | x | User-provided value |
|
||||
|
||||
Reference in New Issue
Block a user