1
1
private import csharp
2
2
private import cil
3
3
private import dotnet
4
+ private import DataFlowPublic
4
5
private import DataFlowPrivate
5
- private import DelegateDataFlow
6
6
private import FlowSummaryImpl as FlowSummaryImpl
7
7
private import semmle.code.csharp.dataflow.FlowSummary
8
8
private import semmle.code.csharp.dispatch.Dispatch
@@ -131,51 +131,24 @@ private module Cached {
131
131
import Cached
132
132
133
133
private module DispatchImpl {
134
- private import CallContext
135
-
136
- /**
137
- * Gets a viable run-time target for the delegate call `call`, requiring
138
- * call context `cc`.
139
- */
140
- private DataFlowCallable viableDelegateCallable ( DataFlowCall call , CallContext cc ) {
141
- result = call .( DelegateDataFlowCall ) .getARuntimeTarget ( cc )
142
- }
143
-
144
134
/**
145
135
* Holds if the set of viable implementations that can be called by `call`
146
136
* might be improved by knowing the call context. This is the case if the
147
137
* call is a delegate call, or if the qualifier accesses a parameter of
148
138
* the enclosing callable `c` (including the implicit `this` parameter).
149
139
*/
150
- predicate mayBenefitFromCallContext ( DataFlowCall call , Callable c ) {
140
+ predicate mayBenefitFromCallContext ( NonDelegateDataFlowCall call , Callable c ) {
151
141
c = call .getEnclosingCallable ( ) and
152
- (
153
- exists ( CallContext cc | exists ( viableDelegateCallable ( call , cc ) ) |
154
- not cc instanceof EmptyCallContext
155
- )
156
- or
157
- call .( NonDelegateDataFlowCall ) .getDispatchCall ( ) .mayBenefitFromCallContext ( )
158
- )
142
+ call .getDispatchCall ( ) .mayBenefitFromCallContext ( )
159
143
}
160
144
161
145
/**
162
146
* Gets a viable dispatch target of `call` in the context `ctx`. This is
163
147
* restricted to those `call`s for which a context might make a difference.
164
148
*/
165
- DataFlowCallable viableImplInCallContext ( DataFlowCall call , DataFlowCall ctx ) {
166
- exists ( ArgumentCallContext cc | result = viableDelegateCallable ( call , cc ) |
167
- cc .isArgument ( ctx .getExpr ( ) , _)
168
- )
169
- or
170
- exists ( DataFlowCallable enclosing |
171
- mayBenefitFromCallContext ( call , enclosing ) and
172
- ctx .getARuntimeTarget ( ) = enclosing and
173
- result = viableDelegateCallable ( call , any ( EmptyCallContext ecc ) )
174
- )
175
- or
149
+ DataFlowCallable viableImplInCallContext ( NonDelegateDataFlowCall call , DataFlowCall ctx ) {
176
150
result =
177
- call .( NonDelegateDataFlowCall )
178
- .getDispatchCall ( )
151
+ call .getDispatchCall ( )
179
152
.getADynamicTargetInCallContext ( ctx .( NonDelegateDataFlowCall ) .getDispatchCall ( ) )
180
153
.getUnboundDeclaration ( )
181
154
}
@@ -307,12 +280,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
307
280
}
308
281
309
282
/** A delegate call relevant for data flow. */
310
- abstract class DelegateDataFlowCall extends DataFlowCall {
311
- /** Gets a viable run-time target of this call requiring call context `cc`. */
312
- abstract DataFlowCallable getARuntimeTarget ( CallContext:: CallContext cc ) ;
313
-
314
- override DataFlowCallable getARuntimeTarget ( ) { result = this .getARuntimeTarget ( _) }
315
- }
283
+ abstract class DelegateDataFlowCall extends DataFlowCall { }
316
284
317
285
/** An explicit delegate or function pointer call relevant for data flow. */
318
286
class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall , TExplicitDelegateLikeCall {
@@ -321,8 +289,11 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
321
289
322
290
ExplicitDelegateLikeDataFlowCall ( ) { this = TExplicitDelegateLikeCall ( cfn , dc ) }
323
291
324
- override DataFlowCallable getARuntimeTarget ( CallContext:: CallContext cc ) {
325
- result = getCallableForDataFlow ( dc .getARuntimeTarget ( cc ) )
292
+ /** Gets the underlying call. */
293
+ DelegateLikeCall getCall ( ) { result = dc }
294
+
295
+ override DataFlowCallable getARuntimeTarget ( ) {
296
+ none ( ) // handled by the shared library
326
297
}
327
298
328
299
override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { result = cfn }
@@ -395,11 +366,11 @@ class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall {
395
366
396
367
SummaryDelegateCall ( ) { this = TSummaryDelegateCall ( c , pos ) }
397
368
398
- override DataFlowCallable getARuntimeTarget ( CallContext :: CallContext cc ) {
399
- exists ( SummaryDelegateParameterSink p |
400
- p . isParameterOf ( c , pos ) and
401
- result = p . getARuntimeTarget ( cc )
402
- )
369
+ /** Gets the parameter node that this delegate call targets. */
370
+ ParameterNode getParameterNode ( ) { result . isParameterOf ( c , pos ) }
371
+
372
+ override DataFlowCallable getARuntimeTarget ( ) {
373
+ none ( ) // handled by the shared library
403
374
}
404
375
405
376
override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { none ( ) }
0 commit comments