@@ -6,7 +6,10 @@ private import rust
66private import codeql.dataflow.internal.FlowSummaryImpl
77private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
88private import codeql.rust.dataflow.internal.DataFlowImpl
9+ private import codeql.rust.internal.PathResolution
910private import codeql.rust.dataflow.FlowSummary
11+ private import codeql.rust.dataflow.Ssa
12+ private import codeql.rust.controlflow.CfgNodes
1013private import Content
1114
1215module Input implements InputSig< Location , RustDataFlow > {
@@ -133,16 +136,40 @@ private module StepsInput implements Impl::Private::StepsInputSig {
133136 result .asCallCfgNode ( ) .getCall ( ) .getStaticTarget ( ) = sc
134137 }
135138
136- RustDataFlow:: Node getSourceNode ( Input:: SourceBase source , Impl:: Private:: SummaryComponent sc ) {
137- sc = Impl:: Private:: SummaryComponent:: return ( _) and
139+ /** Gets the argument of `source` described by `sc`, if any. */
140+ private Expr getSourceNodeArgument ( Input:: SourceBase source , Impl:: Private:: SummaryComponent sc ) {
141+ exists ( ArgumentPosition pos |
142+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
143+ result = pos .getArgument ( source .getCall ( ) )
144+ )
145+ }
146+
147+ /** Get the callable that `expr` refers to. */
148+ private Callable getCallable ( Expr expr ) {
149+ result = resolvePath ( expr .( PathExpr ) .getPath ( ) ) .( Function )
150+ or
151+ result = expr .( ClosureExpr )
152+ or
153+ // The expression is an SSA read of an assignment of a closure
154+ exists ( Ssa:: Definition def , ExprCfgNode value |
155+ def .getARead ( ) .getAstNode ( ) = expr and
156+ def .getAnUltimateDefinition ( ) .( Ssa:: WriteDefinition ) .assigns ( value ) and
157+ result = value .getExpr ( ) .( ClosureExpr )
158+ )
159+ }
160+
161+ RustDataFlow:: Node getSourceNode ( Input:: SourceBase source , Impl:: Private:: SummaryComponentStack s ) {
162+ s .head ( ) = Impl:: Private:: SummaryComponent:: return ( _) and
138163 result .asExpr ( ) .getExpr ( ) = source .getCall ( )
139164 or
140- exists ( CallExprBase call , Expr arg , ArgumentPosition pos |
141- result .( RustDataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) .getExpr ( ) = arg and
142- sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
143- call = source .getCall ( ) and
144- arg = pos .getArgument ( call )
165+ exists ( ArgumentPosition pos , Expr arg |
166+ s .head ( ) = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
167+ arg = getSourceNodeArgument ( source , s .tail ( ) .head ( ) ) and
168+ result .asParameter ( ) = getCallable ( arg ) .getParam ( pos .getPosition ( ) )
145169 )
170+ or
171+ result .( RustDataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) .getExpr ( ) =
172+ getSourceNodeArgument ( source , s .head ( ) )
146173 }
147174
148175 RustDataFlow:: Node getSinkNode ( Input:: SinkBase sink , Impl:: Private:: SummaryComponent sc ) {
0 commit comments