@@ -12,14 +12,6 @@ private import semmle.code.csharp.dispatch.RuntimeCallable
1212private import semmle.code.csharp.frameworks.system.Collections
1313private import semmle.code.csharp.frameworks.system.collections.Generic
1414
15- private predicate summarizedCallable ( DataFlowCallable c ) {
16- c instanceof FlowSummary:: SummarizedCallable
17- or
18- FlowSummaryImpl:: Private:: summaryReturnNode ( _, TJumpReturnKind ( c , _) )
19- or
20- c = interpretElement ( _, _, _, _, _, _)
21- }
22-
2315/**
2416 * Gets a source declaration of callable `c` that has a body or has
2517 * a flow summary.
@@ -29,9 +21,6 @@ private predicate summarizedCallable(DataFlowCallable c) {
2921 */
3022DotNet:: Callable getCallableForDataFlow ( DotNet:: Callable c ) {
3123 exists ( DotNet:: Callable unboundDecl | unboundDecl = c .getUnboundDeclaration ( ) |
32- summarizedCallable ( unboundDecl ) and
33- result = unboundDecl
34- or
3524 result .hasBody ( ) and
3625 if unboundDecl .getFile ( ) .fromSource ( )
3726 then
@@ -81,17 +70,27 @@ newtype TReturnKind =
8170 v = def .getSourceVariable ( ) .getAssignable ( )
8271 )
8372 } or
84- TJumpReturnKind ( DataFlowCallable target , ReturnKind rk ) {
85- rk instanceof NormalReturnKind and
73+ TJumpReturnKind ( Callable target , ReturnKind rk ) {
74+ target . isUnboundDeclaration ( ) and
8675 (
87- target instanceof Constructor or
88- not target .getReturnType ( ) instanceof VoidType
76+ rk instanceof NormalReturnKind and
77+ (
78+ target instanceof Constructor or
79+ not target .getReturnType ( ) instanceof VoidType
80+ )
81+ or
82+ exists ( target .getParameter ( rk .( OutRefReturnKind ) .getPosition ( ) ) )
8983 )
90- or
91- exists ( target .getParameter ( rk .( OutRefReturnKind ) .getPosition ( ) ) )
9284 }
9385
9486private module Cached {
87+ cached
88+ newtype TDataFlowCallable =
89+ TDotNetCallable ( DotNet:: Callable c ) {
90+ c .isUnboundDeclaration ( ) and not c instanceof FlowSummary:: SummarizedCallable
91+ } or
92+ TSummarizedCallable ( FlowSummary:: SummarizedCallable c )
93+
9594 cached
9695 newtype TDataFlowCall =
9796 TNonDelegateCall ( ControlFlow:: Nodes:: ElementNode cfn , DispatchCall dc ) {
@@ -108,7 +107,7 @@ private module Cached {
108107 // No need to include calls that are compiled from source
109108 not call .getImplementation ( ) .getMethod ( ) .compiledFromSource ( )
110109 } or
111- TSummaryCall ( FlowSummary :: SummarizedCallable c , Node receiver ) {
110+ TSummaryCall ( FlowSummaryImpl :: Public :: SummarizedCallable c , Node receiver ) {
112111 FlowSummaryImpl:: Private:: summaryCallbackRange ( c , receiver )
113112 }
114113
@@ -144,7 +143,7 @@ private module DispatchImpl {
144143 * call is a delegate call, or if the qualifier accesses a parameter of
145144 * the enclosing callable `c` (including the implicit `this` parameter).
146145 */
147- predicate mayBenefitFromCallContext ( NonDelegateDataFlowCall call , Callable c ) {
146+ predicate mayBenefitFromCallContext ( NonDelegateDataFlowCall call , DataFlowCallable c ) {
148147 c = call .getEnclosingCallable ( ) and
149148 call .getDispatchCall ( ) .mayBenefitFromCallContext ( )
150149 }
@@ -154,7 +153,7 @@ private module DispatchImpl {
154153 * restricted to those `call`s for which a context might make a difference.
155154 */
156155 DataFlowCallable viableImplInCallContext ( NonDelegateDataFlowCall call , DataFlowCall ctx ) {
157- result =
156+ result . getUnderlyingCallable ( ) =
158157 call .getDispatchCall ( )
159158 .getADynamicTargetInCallContext ( ctx .( NonDelegateDataFlowCall ) .getDispatchCall ( ) )
160159 .getUnboundDeclaration ( )
@@ -233,22 +232,38 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind
233232 * one API entry point and out of another.
234233 */
235234class JumpReturnKind extends ReturnKind , TJumpReturnKind {
236- private DataFlowCallable target ;
235+ private Callable target ;
237236 private ReturnKind rk ;
238237
239238 JumpReturnKind ( ) { this = TJumpReturnKind ( target , rk ) }
240239
241240 /** Gets the target of the jump. */
242- DataFlowCallable getTarget ( ) { result = target }
241+ Callable getTarget ( ) { result = target }
243242
244243 /** Gets the return kind of the target. */
245244 ReturnKind getTargetReturnKind ( ) { result = rk }
246245
247246 override string toString ( ) { result = "jump to " + target }
248247}
249248
250- class DataFlowCallable extends DotNet:: Callable {
251- DataFlowCallable ( ) { this .isUnboundDeclaration ( ) }
249+ /** A callable used for data flow. */
250+ class DataFlowCallable extends TDataFlowCallable {
251+ /** Get the underlying source code callable, if any. */
252+ DotNet:: Callable asCallable ( ) { this = TDotNetCallable ( result ) }
253+
254+ /** Get the underlying summarized callable, if any. */
255+ FlowSummary:: SummarizedCallable asSummarizedCallable ( ) { this = TSummarizedCallable ( result ) }
256+
257+ /** Get the underlying callable. */
258+ DotNet:: Callable getUnderlyingCallable ( ) {
259+ result = this .asCallable ( ) or result = this .asSummarizedCallable ( )
260+ }
261+
262+ /** Gets a textual representation of this dataflow callable. */
263+ string toString ( ) { result = this .getUnderlyingCallable ( ) .toString ( ) }
264+
265+ /** Get the location of this dataflow callable. */
266+ Location getLocation ( ) { result = this .getUnderlyingCallable ( ) .getLocation ( ) }
252267}
253268
254269/** A call relevant for data flow. */
@@ -306,18 +321,32 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
306321 DispatchCall getDispatchCall ( ) { result = dc }
307322
308323 override DataFlowCallable getARuntimeTarget ( ) {
309- result = getCallableForDataFlow ( dc .getADynamicTarget ( ) )
324+ result .asCallable ( ) = getCallableForDataFlow ( dc .getADynamicTarget ( ) )
325+ or
326+ exists ( Callable c , boolean static |
327+ result .asSummarizedCallable ( ) = c and
328+ c = this .getATarget ( static )
329+ |
330+ static = false
331+ or
332+ static = true and not c instanceof RuntimeCallable
333+ )
334+ }
335+
336+ /** Gets a static or dynamic target of this call. */
337+ Callable getATarget ( boolean static ) {
338+ result = dc .getADynamicTarget ( ) .getUnboundDeclaration ( ) and static = false
310339 or
311- result = dc .getAStaticTarget ( ) .getUnboundDeclaration ( ) and
312- summarizedCallable ( result ) and
313- not result instanceof RuntimeCallable
340+ result = dc .getAStaticTarget ( ) .getUnboundDeclaration ( ) and static = true
314341 }
315342
316343 override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { result = cfn }
317344
318345 override DataFlow:: ExprNode getNode ( ) { result .getControlFlowNode ( ) = cfn }
319346
320- override DataFlowCallable getEnclosingCallable ( ) { result = cfn .getEnclosingCallable ( ) }
347+ override DataFlowCallable getEnclosingCallable ( ) {
348+ result .getUnderlyingCallable ( ) = cfn .getEnclosingCallable ( )
349+ }
321350
322351 override string toString ( ) { result = cfn .toString ( ) }
323352
@@ -345,7 +374,9 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
345374
346375 override DataFlow:: ExprNode getNode ( ) { result .getControlFlowNode ( ) = cfn }
347376
348- override DataFlowCallable getEnclosingCallable ( ) { result = cfn .getEnclosingCallable ( ) }
377+ override DataFlowCallable getEnclosingCallable ( ) {
378+ result .getUnderlyingCallable ( ) = cfn .getEnclosingCallable ( )
379+ }
349380
350381 override string toString ( ) { result = cfn .toString ( ) }
351382
@@ -363,13 +394,15 @@ class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCa
363394
364395 TransitiveCapturedDataFlowCall ( ) { this = TTransitiveCapturedCall ( cfn , target ) }
365396
366- override DataFlowCallable getARuntimeTarget ( ) { result = target }
397+ override DataFlowCallable getARuntimeTarget ( ) { result . getUnderlyingCallable ( ) = target }
367398
368399 override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { result = cfn }
369400
370401 override DataFlow:: ExprNode getNode ( ) { none ( ) }
371402
372- override DataFlowCallable getEnclosingCallable ( ) { result = cfn .getEnclosingCallable ( ) }
403+ override DataFlowCallable getEnclosingCallable ( ) {
404+ result .getUnderlyingCallable ( ) = cfn .getEnclosingCallable ( )
405+ }
373406
374407 override string toString ( ) { result = "[transitive] " + cfn .toString ( ) }
375408
@@ -384,14 +417,16 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
384417
385418 override DataFlowCallable getARuntimeTarget ( ) {
386419 // There is no dispatch library for CIL, so do not consider overrides for now
387- result = getCallableForDataFlow ( call .getTarget ( ) )
420+ result . getUnderlyingCallable ( ) = getCallableForDataFlow ( call .getTarget ( ) )
388421 }
389422
390423 override ControlFlow:: Nodes:: ElementNode getControlFlowNode ( ) { none ( ) }
391424
392425 override DataFlow:: ExprNode getNode ( ) { result .getExpr ( ) = call }
393426
394- override DataFlowCallable getEnclosingCallable ( ) { result = call .getEnclosingCallable ( ) }
427+ override DataFlowCallable getEnclosingCallable ( ) {
428+ result .getUnderlyingCallable ( ) = call .getEnclosingCallable ( )
429+ }
395430
396431 override string toString ( ) { result = call .toString ( ) }
397432
@@ -406,7 +441,7 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
406441 * the method `Select`.
407442 */
408443class SummaryCall extends DelegateDataFlowCall , TSummaryCall {
409- private FlowSummary :: SummarizedCallable c ;
444+ private FlowSummaryImpl :: Public :: SummarizedCallable c ;
410445 private Node receiver ;
411446
412447 SummaryCall ( ) { this = TSummaryCall ( c , receiver ) }
@@ -422,7 +457,7 @@ class SummaryCall extends DelegateDataFlowCall, TSummaryCall {
422457
423458 override DataFlow:: Node getNode ( ) { none ( ) }
424459
425- override DataFlowCallable getEnclosingCallable ( ) { result = c }
460+ override DataFlowCallable getEnclosingCallable ( ) { result . asSummarizedCallable ( ) = c }
426461
427462 override string toString ( ) { result = "[summary] call to " + receiver + " in " + c }
428463
0 commit comments