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,45 +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
149
+ DataFlowCallable viableImplInCallContext ( NonDelegateDataFlowCall call , DataFlowCall ctx ) {
170
150
result =
171
- call .( NonDelegateDataFlowCall )
172
- .getDispatchCall ( )
151
+ call .getDispatchCall ( )
173
152
.getADynamicTargetInCallContext ( ctx .( NonDelegateDataFlowCall ) .getDispatchCall ( ) )
174
153
.getUnboundDeclaration ( )
175
154
}
@@ -302,10 +281,9 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
302
281
303
282
/** A delegate call relevant for data flow. */
304
283
abstract class DelegateDataFlowCall extends DataFlowCall {
305
- /** Gets a viable run-time target of this call requiring call context `cc`. */
306
- abstract DataFlowCallable getARuntimeTarget ( CallContext:: CallContext cc ) ;
307
-
308
- override DataFlowCallable getARuntimeTarget ( ) { result = this .getARuntimeTarget ( _) }
284
+ override DataFlowCallable getARuntimeTarget ( ) {
285
+ none ( ) // handled by the shared library
286
+ }
309
287
}
310
288
311
289
/** An explicit delegate or function pointer call relevant for data flow. */
@@ -315,9 +293,8 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
315
293
316
294
ExplicitDelegateLikeDataFlowCall ( ) { this = TExplicitDelegateLikeCall ( cfn , dc ) }
317
295
318
- override DataFlowCallable getARuntimeTarget ( CallContext:: CallContext cc ) {
319
- result = getCallableForDataFlow ( dc .getARuntimeTarget ( cc ) )
320
- }
296
+ /** Gets the underlying call. */
297
+ DelegateLikeCall getCall ( ) { result = dc }
321
298
322
299
override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { result = cfn }
323
300
@@ -389,12 +366,8 @@ class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall {
389
366
390
367
SummaryDelegateCall ( ) { this = TSummaryDelegateCall ( c , pos ) }
391
368
392
- override DataFlowCallable getARuntimeTarget ( CallContext:: CallContext cc ) {
393
- exists ( SummaryDelegateParameterSink p |
394
- p .isParameterOf ( c , pos ) and
395
- result = p .getARuntimeTarget ( cc )
396
- )
397
- }
369
+ /** Gets the parameter node that this delegate call targets. */
370
+ ParameterNode getParameterNode ( ) { result .isParameterOf ( c , pos ) }
398
371
399
372
override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { none ( ) }
400
373
0 commit comments