Skip to content

Commit bc6d38e

Browse files
committed
Address review comments
1 parent 38a572d commit bc6d38e

File tree

28 files changed

+328
-247
lines changed

28 files changed

+328
-247
lines changed

rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ final class CallExprCfgNode extends Nodes::CallExprCfgNode {
258258

259259
/** Gets the `i`th argument of this call. */
260260
ExprCfgNode getSyntacticArgument(int i) {
261-
any(ChildMapping mapping).hasCfgChild(node, node.getSyntacticArgument(i), this, result)
261+
any(ChildMapping mapping)
262+
.hasCfgChild(node, node.getSyntacticPositionalArgument(i), this, result)
262263
}
263264
}
264265

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,18 @@ module ExprTrees {
210210
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
211211
}
212212

213-
class ArgsExprTree extends StandardPostOrderTree instanceof ArgsExpr {
214-
ArgsExprTree() {
213+
class InvocationExprTree extends StandardPostOrderTree instanceof InvocationExpr {
214+
InvocationExprTree() {
215215
not this instanceof CallExpr and
216216
not this instanceof BinaryLogicalOperation
217217
}
218218

219-
override AstNode getChildNode(int i) { result = super.getSyntacticArgument(i) }
219+
override AstNode getChildNode(int i) {
220+
i = 0 and
221+
result = super.getSyntacticReceiver()
222+
or
223+
result = super.getSyntacticPositionalArgument(i - 1)
224+
}
220225
}
221226

222227
class LogicalOrExprTree extends PostOrderTree, LogicalOrExpr {
@@ -295,7 +300,7 @@ module ExprTrees {
295300
override AstNode getChildNode(int i) {
296301
i = 0 and result = super.getFunction()
297302
or
298-
result = super.getSyntacticArgument(i - 1)
303+
result = super.getSyntacticPositionalArgument(i - 1)
299304
}
300305
}
301306

@@ -533,10 +538,6 @@ module ExprTrees {
533538
}
534539
}
535540

536-
class RefExprTree extends StandardPostOrderTree instanceof RefExpr {
537-
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
538-
}
539-
540541
class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr {
541542
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
542543
}

rust/ql/lib/codeql/rust/dataflow/internal/Content.qll

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
private import rust
66
private import codeql.rust.frameworks.stdlib.Builtins
77
private import DataFlowImpl
8+
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
89

910
/**
1011
* A path to a value contained in an object. For example a field name of a struct.
@@ -168,10 +169,10 @@ final class TuplePositionContent extends FieldContent, TTuplePositionContent {
168169
* Used by the model generator to create flow summaries for higher-order
169170
* functions.
170171
*/
171-
final class ClosureCallArgumentContent extends Content, TClosureCallArgumentContent {
172+
final class FunctionCallArgumentContent extends Content, TFunctionCallArgumentContent {
172173
private int pos;
173174

174-
ClosureCallArgumentContent() { this = TClosureCallArgumentContent(pos) }
175+
FunctionCallArgumentContent() { this = TFunctionCallArgumentContent(pos) }
175176

176177
int getPosition() { result = pos }
177178

@@ -269,8 +270,8 @@ newtype TContent =
269270
)]
270271
} or
271272
TFunctionCallReturnContent() or
272-
TClosureCallArgumentContent(int pos) {
273-
pos in [0 .. any(ClosureCallExpr c).getNumberOfPositionalArguments()]
273+
TFunctionCallArgumentContent(int pos) {
274+
pos in [0 .. any(CallExprImpl::DynamicCallExpr c).getNumberOfPositionalArguments()]
274275
} or
275276
TCapturedVariableContent(VariableCapture::CapturedVariable v) or
276277
TReferenceContent()

rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ private import codeql.dataflow.internal.DataFlowImpl
1010
private import rust
1111
private import SsaImpl as SsaImpl
1212
private import codeql.rust.controlflow.internal.Scope as Scope
13+
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
1314
private import codeql.rust.internal.PathResolution
1415
private import codeql.rust.controlflow.ControlFlowGraph
1516
private import codeql.rust.dataflow.Ssa
@@ -85,62 +86,10 @@ final class DataFlowCall extends TDataFlowCall {
8586
Location getLocation() { result = this.asCall().getLocation() }
8687
}
8788

88-
/**
89-
* The position of a parameter in a function.
90-
*
91-
* In Rust there is a 1-to-1 correspondence between parameter positions and
92-
* arguments positions, so we use the same underlying type for both.
93-
*/
94-
final class ParameterPosition extends TParameterPosition {
95-
/** Gets the underlying integer position, if any. */
96-
int getPosition() { this = TPositionalParameterPosition(result) }
97-
98-
predicate hasPosition() { exists(this.getPosition()) }
99-
100-
/** Holds if this position represents the `self` position. */
101-
predicate isSelf() { this = TSelfParameterPosition() }
102-
103-
/**
104-
* Holds if this position represents a reference to a closure itself. Only
105-
* used for tracking flow through captured variables.
106-
*/
107-
predicate isClosureSelf() { this = TClosureSelfParameterPosition() }
108-
109-
/** Gets a textual representation of this position. */
110-
string toString() {
111-
result = this.getPosition().toString()
112-
or
113-
result = "self" and this.isSelf()
114-
or
115-
result = "closure self" and this.isClosureSelf()
116-
}
117-
118-
ParamBase getParameterIn(ParamList ps) {
119-
result = ps.getParam(this.getPosition())
120-
or
121-
result = ps.getSelfParam() and this.isSelf()
122-
}
123-
}
124-
125-
/**
126-
* The position of an argument in a call.
127-
*
128-
* In Rust there is a 1-to-1 correspondence between parameter positions and
129-
* arguments positions, so we use the same underlying type for both.
130-
*/
131-
final class ArgumentPosition extends ParameterPosition {
132-
/** Gets the argument of `call` at this position, if any. */
133-
Expr getArgument(Call call) {
134-
result = call.getPositionalArgument(this.getPosition())
135-
or
136-
result = call.(MethodCall).getReceiver() and this.isSelf()
137-
}
138-
}
139-
14089
/**
14190
* Holds if `arg` is an argument of `call` at the position `pos`.
14291
*/
143-
predicate isArgumentForCall(Expr arg, Call call, ArgumentPosition pos) {
92+
predicate isArgumentForCall(Expr arg, Call call, RustDataFlow::ArgumentPosition pos) {
14493
// TODO: Handle index expressions as calls in data flow.
14594
not call instanceof IndexExpr and
14695
arg = pos.getArgument(call)
@@ -292,8 +241,8 @@ predicate lambdaCreationExpr(Expr creation) {
292241
* Holds if `call` is a lambda call of kind `kind` where `receiver` is the
293242
* invoked expression.
294243
*/
295-
predicate lambdaCallExpr(ClosureCallExpr call, LambdaCallKind kind, Expr receiver) {
296-
receiver = call.getClosureExpr() and
244+
predicate lambdaCallExpr(CallExprImpl::DynamicCallExpr call, LambdaCallKind kind, Expr receiver) {
245+
receiver = call.getFunction() and
297246
exists(kind)
298247
}
299248

@@ -305,10 +254,6 @@ private module Aliases {
305254

306255
class DataFlowCallAlias = DataFlowCall;
307256

308-
class ParameterPositionAlias = ParameterPosition;
309-
310-
class ArgumentPositionAlias = ArgumentPosition;
311-
312257
class ContentAlias = Content;
313258

314259
class ContentSetAlias = ContentSet;
@@ -340,6 +285,58 @@ module RustDataFlow implements InputSig<Location> {
340285

341286
final class CastNode = Node::CastNode;
342287

288+
/**
289+
* The position of a parameter in a function.
290+
*
291+
* In Rust there is a 1-to-1 correspondence between parameter positions and
292+
* arguments positions, so we use the same underlying type for both.
293+
*/
294+
final class ParameterPosition extends TParameterPosition {
295+
/** Gets the underlying integer position, if any. */
296+
int getPosition() { this = TPositionalParameterPosition(result) }
297+
298+
predicate hasPosition() { exists(this.getPosition()) }
299+
300+
/** Holds if this position represents the `self` position. */
301+
predicate isSelf() { this = TSelfParameterPosition() }
302+
303+
/**
304+
* Holds if this position represents a reference to a closure itself. Only
305+
* used for tracking flow through captured variables.
306+
*/
307+
predicate isClosureSelf() { this = TClosureSelfParameterPosition() }
308+
309+
/** Gets a textual representation of this position. */
310+
string toString() {
311+
result = this.getPosition().toString()
312+
or
313+
result = "self" and this.isSelf()
314+
or
315+
result = "closure self" and this.isClosureSelf()
316+
}
317+
318+
ParamBase getParameterIn(ParamList ps) {
319+
result = ps.getParam(this.getPosition())
320+
or
321+
result = ps.getSelfParam() and this.isSelf()
322+
}
323+
}
324+
325+
/**
326+
* The position of an argument in a call.
327+
*
328+
* In Rust there is a 1-to-1 correspondence between parameter positions and
329+
* arguments positions, so we use the same underlying type for both.
330+
*/
331+
final class ArgumentPosition extends ParameterPosition {
332+
/** Gets the argument of `call` at this position, if any. */
333+
Expr getArgument(Call call) {
334+
result = call.getPositionalArgument(this.getPosition())
335+
or
336+
result = call.(MethodCall).getReceiver() and this.isSelf()
337+
}
338+
}
339+
343340
/** Holds if `p` is a parameter of `c` at the position `pos`. */
344341
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
345342
p.isParameterOf(c, pos)
@@ -449,10 +446,6 @@ module RustDataFlow implements InputSig<Location> {
449446

450447
ContentApprox getContentApprox(Content c) { result = c }
451448

452-
class ParameterPosition = ParameterPositionAlias;
453-
454-
class ArgumentPosition = ArgumentPositionAlias;
455-
456449
/**
457450
* Holds if the parameter position `ppos` matches the argument position
458451
* `apos`.
@@ -664,7 +657,7 @@ module RustDataFlow implements InputSig<Location> {
664657
pragma[nomagic]
665658
additional predicate storeContentStep(Node node1, Content c, Node node2) {
666659
exists(CallExpr ce, TupleField tf, int pos |
667-
node1.asExpr() = ce.getSyntacticArgument(pos) and
660+
node1.asExpr() = ce.getSyntacticPositionalArgument(pos) and
668661
node2.asExpr() = ce and
669662
c = TTupleFieldContent(tf)
670663
|
@@ -716,7 +709,7 @@ module RustDataFlow implements InputSig<Location> {
716709
exists(DataFlowCall call, int i |
717710
isArgumentNode(node1, call, TPositionalParameterPosition(i)) and
718711
lambdaCall(call, _, node2.(PostUpdateNode).getPreUpdateNode()) and
719-
c.(ClosureCallArgumentContent).getPosition() = i
712+
c.(FunctionCallArgumentContent).getPosition() = i
720713
)
721714
or
722715
VariableCapture::storeStep(node1, c, node2)
@@ -825,7 +818,7 @@ module RustDataFlow implements InputSig<Location> {
825818
*/
826819
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
827820
(
828-
receiver.asExpr() = call.asCall().(ClosureCallExpr).getClosureExpr()
821+
receiver.asExpr() = call.asCall().(CallExprImpl::DynamicCallExpr).getFunction()
829822
or
830823
call.isSummaryCall(_, receiver.(FlowSummaryNode).getSummaryNode())
831824
) and

rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module Input implements InputSig<Location, RustDataFlow> {
5050

5151
ReturnKind getStandardReturnValueKind() { result = TNormalReturnKind() }
5252

53-
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
53+
string encodeParameterPosition(RustDataFlow::ParameterPosition pos) { result = pos.toString() }
5454

5555
string encodeArgumentPosition(RustDataFlow::ArgumentPosition pos) { result = pos.toString() }
5656

@@ -105,7 +105,9 @@ module Input implements InputSig<Location, RustDataFlow> {
105105
string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) }
106106

107107
bindingset[token]
108-
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
108+
RustDataFlow::ParameterPosition decodeUnknownParameterPosition(
109+
AccessPath::AccessPathTokenBase token
110+
) {
109111
// needed to support `Argument[x..y]` ranges
110112
token.getName() = "Argument" and
111113
result.getPosition() = AccessPath::parseInt(token.getAnArgument())
@@ -132,7 +134,7 @@ private module StepsInput implements Impl::Private::StepsInputSig {
132134

133135
/** Gets the argument of `source` described by `sc`, if any. */
134136
private Expr getSourceNodeArgument(Input::SourceBase source, Impl::Private::SummaryComponent sc) {
135-
exists(ArgumentPosition pos |
137+
exists(RustDataFlow::ArgumentPosition pos |
136138
sc = Impl::Private::SummaryComponent::argument(pos) and
137139
result = pos.getArgument(source.getCall())
138140
)
@@ -159,7 +161,7 @@ private module StepsInput implements Impl::Private::StepsInputSig {
159161
s.head() = Impl::Private::SummaryComponent::return(_) and
160162
result.asExpr() = source.getCall()
161163
or
162-
exists(ArgumentPosition pos, Expr arg |
164+
exists(RustDataFlow::ArgumentPosition pos, Expr arg |
163165
s.head() = Impl::Private::SummaryComponent::parameter(pos) and
164166
arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and
165167
result.asParameter() = getCallable(arg).getParam(pos.getPosition())
@@ -170,7 +172,7 @@ private module StepsInput implements Impl::Private::StepsInputSig {
170172
}
171173

172174
RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) {
173-
exists(ArgsExpr call, Expr arg, ArgumentPosition pos |
175+
exists(InvocationExpr call, Expr arg, RustDataFlow::ArgumentPosition pos |
174176
result.asExpr() = arg and
175177
sc = Impl::Private::SummaryComponent::argument(pos) and
176178
call = sink.getCall() and

rust/ql/lib/codeql/rust/dataflow/internal/Node.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,34 +167,34 @@ final class NameNode extends AstNodeNode, TNameNode {
167167
*/
168168
abstract class ParameterNode extends Node {
169169
/** Holds if this node is a parameter of `c` at position `pos`. */
170-
abstract predicate isParameterOf(DataFlowCallable c, ParameterPosition pos);
170+
abstract predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos);
171171
}
172172

173173
final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParameterNode {
174174
override ParamBase n;
175175

176176
SourceParameterNode() { this = TSourceParameterNode(n) }
177177

178-
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
178+
override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) {
179179
n = pos.getParameterIn(c.asCfgScope().(Callable).getParamList())
180180
}
181181

182182
/** Get the parameter position of this parameter. */
183-
ParameterPosition getPosition() { this.isParameterOf(_, result) }
183+
RustDataFlow::ParameterPosition getPosition() { this.isParameterOf(_, result) }
184184

185185
/** Gets the parameter in the CFG that this node corresponds to. */
186186
ParamBase getParameter() { result = n }
187187
}
188188

189189
/** A parameter for a library callable with a flow summary. */
190190
final class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
191-
private ParameterPosition pos_;
191+
private RustDataFlow::ParameterPosition pos_;
192192

193193
SummaryParameterNode() {
194194
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_)
195195
}
196196

197-
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
197+
override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) {
198198
this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_
199199
}
200200
}
@@ -210,7 +210,7 @@ final class ClosureParameterNode extends ParameterNode, TClosureSelfReferenceNod
210210

211211
final override CfgScope getCfgScope() { result = cfgScope }
212212

213-
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
213+
override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) {
214214
cfgScope = c.asCfgScope() and pos.isClosureSelf()
215215
}
216216

rust/ql/lib/codeql/rust/elements/ArgsExpr.qll

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)