@@ -14,8 +14,14 @@ private import semmle.code.csharp.dataflow.FlowSummary
1414private import semmle.code.csharp.dispatch.Dispatch
1515private import semmle.code.csharp.frameworks.system.linq.Expressions
1616
17+ /** A source of flow for a delegate or function pointer expression. */
18+ abstract private class DelegateLikeFlowSource extends DataFlow:: ExprNode {
19+ /** Gets the callable that is referenced in this delegate or function pointer flow source. */
20+ abstract Callable getCallable ( ) ;
21+ }
22+
1723/** A source of flow for a delegate expression. */
18- private class DelegateFlowSource extends DataFlow :: ExprNode {
24+ private class DelegateFlowSource extends DelegateLikeFlowSource {
1925 Callable c ;
2026
2127 DelegateFlowSource ( ) {
@@ -27,11 +33,29 @@ private class DelegateFlowSource extends DataFlow::ExprNode {
2733 }
2834
2935 /** Gets the callable that is referenced in this delegate flow source. */
30- Callable getCallable ( ) { result = c }
36+ override Callable getCallable ( ) { result = c }
3137}
3238
33- /** A sink of flow for a delegate expression. */
34- abstract private class DelegateFlowSink extends DataFlow:: Node {
39+ /** A source of flow for a function pointer expression. */
40+ private class FunctionPointerFlowSource extends DelegateLikeFlowSource {
41+ Callable c ;
42+
43+ FunctionPointerFlowSource ( ) {
44+ c =
45+ this .getExpr ( )
46+ .( AddressOfExpr )
47+ .getOperand ( )
48+ .( CallableAccess )
49+ .getTarget ( )
50+ .getUnboundDeclaration ( )
51+ }
52+
53+ /** Gets the callable that is referenced in this function pointer flow source. */
54+ override Callable getCallable ( ) { result = c }
55+ }
56+
57+ /** A sink of flow for a delegate or function pointer expression. */
58+ abstract private class DelegateLikeFlowSink extends DataFlow:: Node {
3559 /**
3660 * Gets an actual run-time target of this delegate call in the given call
3761 * context, if any. The call context records the *last* call required to
@@ -85,33 +109,33 @@ abstract private class DelegateFlowSink extends DataFlow::Node {
85109 */
86110 cached
87111 Callable getARuntimeTarget ( CallContext context ) {
88- exists ( DelegateFlowSource dfs |
112+ exists ( DelegateLikeFlowSource dfs |
89113 flowsFrom ( this , dfs , _, context ) and
90114 result = dfs .getCallable ( )
91115 )
92116 }
93117}
94118
95- /** A delegate call expression. */
96- class DelegateCallExpr extends DelegateFlowSink , DataFlow:: ExprNode {
97- DelegateCall dc ;
119+ /** A delegate or function pointer call expression. */
120+ class DelegateLikeCallExpr extends DelegateLikeFlowSink , DataFlow:: ExprNode {
121+ DelegateLikeCall dc ;
98122
99- DelegateCallExpr ( ) { this .getExpr ( ) = dc .getDelegateExpr ( ) }
123+ DelegateLikeCallExpr ( ) { this .getExpr ( ) = dc .getExpr ( ) }
100124
101- /** Gets the delegate call that this expression belongs to. */
102- DelegateCall getDelegateCall ( ) { result = dc }
125+ /** Gets the delegate or function pointer call that this expression belongs to. */
126+ DelegateLikeCall getCall ( ) { result = dc }
103127}
104128
105129/** A parameter of delegate type belonging to a callable with a flow summary. */
106- class SummaryDelegateParameterSink extends DelegateFlowSink , ParameterNode {
130+ class SummaryDelegateParameterSink extends DelegateLikeFlowSink , ParameterNode {
107131 SummaryDelegateParameterSink ( ) {
108132 this .getType ( ) instanceof SystemLinqExpressions:: DelegateExtType and
109133 this .isParameterOf ( any ( SummarizedCallable c ) , _)
110134 }
111135}
112136
113137/** A delegate expression that is added to an event. */
114- class AddEventSource extends DelegateFlowSink , DataFlow:: ExprNode {
138+ class AddEventSource extends DelegateLikeFlowSink , DataFlow:: ExprNode {
115139 AddEventExpr ae ;
116140
117141 AddEventSource ( ) { this .getExpr ( ) = ae .getRValue ( ) }
@@ -150,7 +174,7 @@ private class NormalReturnNode extends Node {
150174 * records the last call on the path from `node` to `sink`, if any.
151175 */
152176private predicate flowsFrom (
153- DelegateFlowSink sink , DataFlow:: Node node , boolean isReturned , CallContext lastCall
177+ DelegateLikeFlowSink sink , DataFlow:: Node node , boolean isReturned , CallContext lastCall
154178) {
155179 // Base case
156180 sink = node and
@@ -188,7 +212,8 @@ private predicate flowsFrom(
188212 or
189213 // Flow into a callable (delegate call)
190214 exists (
191- ParameterNode mid , CallContext prevLastCall , DelegateCall call , Callable c , Parameter p , int i
215+ ParameterNode mid , CallContext prevLastCall , DelegateLikeCall call , Callable c , Parameter p ,
216+ int i
192217 |
193218 flowsFrom ( sink , mid , isReturned , prevLastCall ) and
194219 isReturned = false and
@@ -238,14 +263,14 @@ private predicate flowIntoNonDelegateCall(NonDelegateCall call, Expr arg, DotNet
238263}
239264
240265pragma [ noinline]
241- private predicate flowIntoDelegateCall ( DelegateCall call , Callable c , Expr arg , int i ) {
242- exists ( DelegateFlowSource dfs , DelegateCallExpr dce |
266+ private predicate flowIntoDelegateCall ( DelegateLikeCall call , Callable c , Expr arg , int i ) {
267+ exists ( DelegateLikeFlowSource dfs , DelegateLikeCallExpr dce |
243268 // the call context is irrelevant because the delegate call
244269 // itself will be the context
245270 flowsFrom ( dce , dfs , _, _) and
246271 arg = call .getArgument ( i ) and
247272 c = dfs .getCallable ( ) and
248- call = dce .getDelegateCall ( )
273+ call = dce .getCall ( )
249274 )
250275}
251276
@@ -255,11 +280,13 @@ private predicate flowOutOfNonDelegateCall(NonDelegateCall call, NormalReturnNod
255280}
256281
257282pragma [ noinline]
258- private predicate flowOutOfDelegateCall ( DelegateCall dc , NormalReturnNode ret , CallContext lastCall ) {
259- exists ( DelegateFlowSource dfs , DelegateCallExpr dce , Callable c |
283+ private predicate flowOutOfDelegateCall (
284+ DelegateLikeCall dc , NormalReturnNode ret , CallContext lastCall
285+ ) {
286+ exists ( DelegateLikeFlowSource dfs , DelegateLikeCallExpr dce , Callable c |
260287 flowsFrom ( dce , dfs , _, lastCall ) and
261288 ret .getEnclosingCallable ( ) = c and
262289 c = dfs .getCallable ( ) and
263- dc = dce .getDelegateCall ( )
290+ dc = dce .getCall ( )
264291 )
265292}
0 commit comments