@@ -29,27 +29,22 @@ predicate encodeContentStructField(StructFieldContent c, string arg) {
2929
3030module Input implements InputSig< Location , RustDataFlow > {
3131 private import codeql.rust.frameworks.stdlib.Stdlib
32- private import codeql.util.Void
3332
3433 class SummarizedCallableBase = Function ;
3534
36- class FlowSummaryCallBase = Void ;
35+ class FlowSummaryCallBase extends AstNode {
36+ FlowSummaryCallBase ( ) { none ( ) }
37+ }
3738
3839 predicate callableFromSource ( SummarizedCallableBase c ) { c .fromSource ( ) }
3940
40- abstract private class SourceSinkBase extends AstNode {
41- /** Gets the associated call. */
42- abstract Call getCall ( ) ;
43-
44- /** Holds if the associated call resolves to `path`. */
45- final predicate callResolvesTo ( string path ) {
46- path = this .getCall ( ) .getResolvedTarget ( ) .getCanonicalPath ( )
47- }
41+ DataFlowCallable getSummarizedCallableAsDataFlowCallable ( SummarizedCallableBase c ) {
42+ result .asSummarizedCallable ( ) = c
4843 }
4944
50- abstract class SourceBase extends SourceSinkBase { }
45+ class SourceBase = Function ;
5146
52- abstract class SinkBase extends SourceSinkBase { }
47+ class SinkBase = Function ;
5348
5449 predicate neutralElement (
5550 Input:: SummarizedCallableBase c , string kind , string provenance , boolean isExact
@@ -61,22 +56,6 @@ module Input implements InputSig<Location, RustDataFlow> {
6156 )
6257 }
6358
64- private class CallExprFunction extends SourceBase , SinkBase {
65- private CallExpr call ;
66-
67- CallExprFunction ( ) { this = call .getFunction ( ) }
68-
69- override Call getCall ( ) { result = call }
70- }
71-
72- private class MethodCallExprNameRef extends SourceBase , SinkBase {
73- private MethodCallExpr call ;
74-
75- MethodCallExprNameRef ( ) { this = call .getIdentifier ( ) }
76-
77- override MethodCallExpr getCall ( ) { result = call }
78- }
79-
8059 RustDataFlow:: ArgumentPosition callbackSelfParameterPosition ( ) { result .isClosureSelf ( ) }
8160
8261 ReturnKind getStandardReturnValueKind ( ) { result = TNormalReturnKind ( ) }
@@ -147,18 +126,16 @@ module Input implements InputSig<Location, RustDataFlow> {
147126
148127private import Make< Location , RustDataFlow , Input > as Impl
149128
150- module StepsInput implements Impl:: Private:: StepsInputSig {
151- Impl :: Private :: SummaryNode getSummaryNode ( RustDataFlow :: Node n ) {
152- result = n . ( FlowSummaryNode ) . getSummaryNode ( )
129+ module Input2 implements Impl:: Private:: InputSig2 {
130+ class SourceSinkReportingElement extends AstNode {
131+ DataFlowCallable getEnclosingCallable ( ) { result . asCfgScope ( ) = this . getEnclosingCfgScope ( ) }
153132 }
154133
155- DataFlowCall getACall ( Public:: SummarizedCallable sc ) { result .asCall ( ) .getStaticTarget ( ) = sc }
156-
157- /** Gets the argument of `source` described by `sc`, if any. */
158- private Expr getSourceNodeArgument ( Input:: SourceBase source , Impl:: Private:: SummaryComponent sc ) {
134+ /** Gets the argument of `call` described by `sc`, if any. */
135+ private Expr getArg ( Call call , Impl:: Private:: SummaryComponent sc ) {
159136 exists ( RustDataFlow:: ArgumentPosition pos |
160137 sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
161- result = pos .getArgument ( source . getCall ( ) )
138+ result = pos .getArgument ( call )
162139 )
163140 }
164141
@@ -175,47 +152,98 @@ module StepsInput implements Impl::Private::StepsInputSig {
175152 )
176153 }
177154
178- RustDataFlow:: DataFlowCallable getSourceNodeEnclosingCallable ( Input:: SourceBase source ) {
179- result .asCfgScope ( ) = source .getEnclosingCfgScope ( )
180- }
181-
182- additional RustDataFlow:: Node getSourceNode (
183- Input:: SourceBase source , Impl:: Private:: SummaryComponentStack s , boolean isArgPostUpdate
155+ bindingset [ source, s]
156+ additional SourceSinkReportingElement getSourceEntryElement (
157+ Impl:: Public:: SourceElement source , Impl:: Private:: SummaryComponentStack s , boolean isArg ,
158+ SourceSinkReportingElement exit
184159 ) {
185- s .head ( ) = Impl:: Private:: SummaryComponent:: return ( _) and
186- result .asExpr ( ) = source .getCall ( ) and
187- isArgPostUpdate = false
160+ s .headOfSingleton ( ) = Impl:: Private:: SummaryComponent:: return ( _) and
161+ result .( Call ) .getResolvedTarget ( ) = source and
162+ isArg = false and
163+ exit = result
188164 or
189- exists ( RustDataFlow:: ArgumentPosition pos , Expr arg |
190- s .head ( ) = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
191- arg = getSourceNodeArgument ( source , s .tail ( ) .headOfSingleton ( ) ) and
192- result .asParameter ( ) = getCallable ( arg ) .getParam ( pos .getPosition ( ) ) and
193- isArgPostUpdate = false
165+ exists ( RustDataFlow:: ArgumentPosition pos |
166+ s .head ( ) = Impl:: Private:: SummaryComponent:: parameter ( pos )
167+ |
168+ exists ( Call call , Expr arg |
169+ call .getResolvedTarget ( ) = source and
170+ arg = getArg ( call , s .tail ( ) .headOfSingleton ( ) ) and
171+ exit = pos .getParameter ( getCallable ( arg ) ) and
172+ result = call and
173+ isArg = false
174+ )
175+ or
176+ exists ( Function f |
177+ f = source
178+ or
179+ f .implements ( source )
180+ |
181+ s .length ( ) = 1 and
182+ result = pos .getParameter ( f ) and
183+ exit = result and
184+ isArg = false
185+ )
194186 )
195187 or
196- result .( RustDataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) =
197- getSourceNodeArgument ( source , s .headOfSingleton ( ) ) and
198- isArgPostUpdate = true
188+ exists ( Call call |
189+ call .getResolvedTarget ( ) = source and
190+ result = getArg ( call , s .headOfSingleton ( ) ) and
191+ exit = result and
192+ isArg = true
193+ )
199194 }
200195
201- RustDataFlow:: Node getSourceNode ( Input:: SourceBase source , Impl:: Private:: SummaryComponentStack s ) {
202- result = getSourceNode ( source , s , _)
196+ bindingset [ source, s]
197+ SourceSinkReportingElement getSourceEntryElement (
198+ Impl:: Public:: SourceElement source , Impl:: Private:: SummaryComponentStack s
199+ ) {
200+ result = getSourceEntryElement ( source , s , _, _)
203201 }
204202
205- RustDataFlow:: Node getSinkNode ( Input:: SinkBase sink , Impl:: Private:: SummaryComponent sc ) {
206- exists ( InvocationExpr call , Expr arg , RustDataFlow:: ArgumentPosition pos |
207- result .asExpr ( ) = arg and
208- sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
209- call = sink .getCall ( ) and
210- arg = pos .getArgument ( call )
203+ bindingset [ e, s]
204+ NodePublic getSourceExitNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponentStack s ) {
205+ exists ( Impl:: Public:: SourceElement source , boolean isArg , SourceSinkReportingElement exit |
206+ e = getSourceEntryElement ( source , s , isArg , exit )
207+ |
208+ isArg = false and
209+ result .( Node ) .getAstNode ( ) = exit
210+ or
211+ isArg = true and
212+ result .( PostUpdateNode ) .getPreUpdateNode ( ) .( Node ) .getAstNode ( ) = exit
213+ )
214+ }
215+
216+ SourceSinkReportingElement getSinkExitElement (
217+ Impl:: Public:: SinkElement sink , Impl:: Private:: SummaryComponent sc
218+ ) {
219+ exists ( Call call |
220+ call .getResolvedTarget ( ) = sink and
221+ result = getArg ( call , sc )
211222 )
212223 }
224+
225+ bindingset [ e, sc]
226+ NodePublic getSinkEntryNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponent sc ) {
227+ result .asExpr ( ) = e and
228+ exists ( sc )
229+ }
230+ }
231+
232+ private import Impl:: Private:: Make2< Input2 > as Impl2
233+
234+ module StepsInput implements Impl2:: StepsInputSig {
235+ Impl2:: SummaryNode getSummaryNode ( RustDataFlow:: Node n ) {
236+ result = n .( FlowSummaryNode ) .getSummaryNode ( )
237+ }
238+
239+ DataFlowCall getACall ( Public:: SummarizedCallable sc ) { result .asCall ( ) .getStaticTarget ( ) = sc }
213240}
214241
215242module Private {
216243 import Impl:: Private
244+ import Impl2
217245
218- module Steps = Impl :: Private :: Steps< StepsInput > ;
246+ module Steps = Impl2 :: Steps< StepsInput > ;
219247
220248 private import codeql.rust.dataflow.FlowSource
221249 private import codeql.rust.dataflow.FlowSink
0 commit comments