Skip to content

Commit 92b94c1

Browse files
committed
C#: Include runtime target in TTransitiveCaptureCall
TTransitiveCaptureCall represents a control flow node that may transitively call many different callables which capture a variable from the current scope. Captured variables are represented as synthetic parameters to the callable, at negative indices. However, each of the different targets may capture a different subset of variables from the enclosing scope, so we must include the target along side the CFN in order to prevent incorrect capture flow.
1 parent 1bd0c69 commit 92b94c1

File tree

2 files changed

+6
-5
lines changed

2 files changed

+6
-5
lines changed

csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ private module Cached {
9797
TImplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateArgumentToLibraryCallable arg) {
9898
cfn.getElement() = arg
9999
} or
100-
TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn) {
101-
transitiveCapturedCallTarget(cfn, _)
100+
TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) {
101+
transitiveCapturedCallTarget(cfn, target)
102102
} or
103103
TCilCall(CIL::Call call) {
104104
// No need to include calls that are compiled from source
@@ -418,10 +418,11 @@ class ImplicitDelegateDataFlowCall extends DelegateDataFlowCall, TImplicitDelega
418418
*/
419419
class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCall {
420420
private ControlFlow::Nodes::ElementNode cfn;
421+
private Callable target;
421422

422-
TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn) }
423+
TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn, target) }
423424

424-
override Callable getARuntimeTarget() { transitiveCapturedCallTarget(cfn, result) }
425+
override Callable getARuntimeTarget() { result = target }
425426

426427
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
427428

csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ private module OutNodes {
953953
additionalCalls = false and
954954
call.(ImplicitDelegateDataFlowCall).isArgumentOf(csharpCall(_, cfn), _)
955955
or
956-
additionalCalls = true and call = TTransitiveCapturedCall(cfn)
956+
additionalCalls = true and call = TTransitiveCapturedCall(cfn, _)
957957
)
958958
}
959959

0 commit comments

Comments
 (0)