Skip to content

Commit 991d30f

Browse files
authored
Merge pull request #21161 from hvitved/rust/restrict-implicit-deref-borrow-nodes
Rust: Restrict `ImplicitDerefBorrowNode` to nodes with enclosing CFG scope
2 parents 5d00a4d + 55d4902 commit 991d30f

File tree

2 files changed

+40
-38
lines changed

2 files changed

+40
-38
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ final class DataFlowCall extends TDataFlowCall {
6262
/** Gets the underlying call, if any. */
6363
Call asCall() { this = TCall(result) }
6464

65-
predicate isImplicitDerefCall(AstNode n, DerefChain derefChain, int i, Function target) {
66-
this = TImplicitDerefCall(n, derefChain, i, target)
65+
predicate isImplicitDerefCall(Expr e, DerefChain derefChain, int i, Function target) {
66+
this = TImplicitDerefCall(e, derefChain, i, target)
6767
}
6868

6969
predicate isSummaryCall(
@@ -75,18 +75,17 @@ final class DataFlowCall extends TDataFlowCall {
7575
DataFlowCallable getEnclosingCallable() {
7676
result.asCfgScope() = this.asCall().getEnclosingCfgScope()
7777
or
78-
result.asCfgScope() =
79-
any(AstNode n | this.isImplicitDerefCall(n, _, _, _)).getEnclosingCfgScope()
78+
result.asCfgScope() = any(Expr e | this.isImplicitDerefCall(e, _, _, _)).getEnclosingCfgScope()
8079
or
8180
this.isSummaryCall(result.asSummarizedCallable(), _)
8281
}
8382

8483
string toString() {
8584
result = this.asCall().toString()
8685
or
87-
exists(AstNode n, DerefChain derefChain, int i |
88-
this.isImplicitDerefCall(n, derefChain, i, _) and
89-
result = "[implicit deref call " + i + " in " + derefChain.toString() + "] " + n
86+
exists(Expr e, DerefChain derefChain, int i |
87+
this.isImplicitDerefCall(e, derefChain, i, _) and
88+
result = "[implicit deref call " + i + " in " + derefChain.toString() + "] " + e
9089
)
9190
or
9291
exists(
@@ -100,7 +99,7 @@ final class DataFlowCall extends TDataFlowCall {
10099
Location getLocation() {
101100
result = this.asCall().getLocation()
102101
or
103-
result = any(AstNode n | this.isImplicitDerefCall(n, _, _, _)).getLocation()
102+
result = any(Expr e | this.isImplicitDerefCall(e, _, _, _)).getLocation()
104103
}
105104
}
106105

@@ -1095,9 +1094,10 @@ private module Cached {
10951094
Stages::DataFlowStage::ref() and
10961095
call.hasEnclosingCfgScope()
10971096
} or
1098-
TImplicitDerefCall(AstNode n, DerefChain derefChain, int i, Function target) {
1099-
TypeInference::implicitDerefChainBorrow(n, derefChain, _) and
1100-
target = derefChain.getElement(i).getDerefFunction()
1097+
TImplicitDerefCall(Expr e, DerefChain derefChain, int i, Function target) {
1098+
TypeInference::implicitDerefChainBorrow(e, derefChain, _) and
1099+
target = derefChain.getElement(i).getDerefFunction() and
1100+
e.hasEnclosingCfgScope()
11011101
} or
11021102
TSummaryCall(
11031103
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver

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

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ abstract class ImplicitDerefBorrowNode extends Node {
277277
*/
278278
abstract Node getBorrowInputNode();
279279

280-
abstract AstNode getUnderlyingAstNode();
280+
abstract Expr getExpr();
281281

282-
override CfgScope getCfgScope() { result = this.getUnderlyingAstNode().getEnclosingCfgScope() }
282+
override CfgScope getCfgScope() { result = this.getExpr().getEnclosingCfgScope() }
283283

284-
override Location getLocation() { result = this.getUnderlyingAstNode().getLocation() }
284+
override Location getLocation() { result = this.getExpr().getLocation() }
285285
}
286286

287287
/**
@@ -292,24 +292,24 @@ abstract class ImplicitDerefBorrowNode extends Node {
292292
* is in.
293293
*/
294294
class ImplicitDerefNode extends ImplicitDerefBorrowNode, TImplicitDerefNode {
295-
AstNode n;
295+
Expr e;
296296
DerefChain derefChain;
297297
ImplicitDerefNodeState state;
298298
int i;
299299

300-
ImplicitDerefNode() { this = TImplicitDerefNode(n, derefChain, state, i, false) }
300+
ImplicitDerefNode() { this = TImplicitDerefNode(e, derefChain, state, i, false) }
301301

302-
override AstNode getUnderlyingAstNode() { result = n }
302+
override Expr getExpr() { result = e }
303303

304304
private predicate isBuiltinDeref() { derefChain.isBuiltinDeref(i) }
305305

306306
private Node getInputNode() {
307307
// The first implicit deref has the underlying AST node as input
308308
i = 0 and
309-
result.(AstNodeNode).getAstNode() = n
309+
result.asExpr() = e
310310
or
311311
// Subsequent implicit derefs have the previous implicit deref as input
312-
result = TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(), i - 1, false)
312+
result = TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(), i - 1, false)
313313
}
314314

315315
/**
@@ -334,19 +334,19 @@ class ImplicitDerefNode extends ImplicitDerefBorrowNode, TImplicitDerefNode {
334334
*/
335335
Node getDerefOutputNode() {
336336
state = TImplicitDerefNodeBeforeDerefState() and
337-
result = TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(), i, false)
337+
result = TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(), i, false)
338338
}
339339

340340
/**
341341
* Holds if this node represents the last implicit deref in the underlying chain.
342342
*/
343-
predicate isLast(AstNode node) {
344-
node = n and
343+
predicate isLast(Expr expr) {
344+
expr = e and
345345
state = TImplicitDerefNodeAfterDerefState() and
346346
i = derefChain.length() - 1
347347
}
348348

349-
override string toString() { result = n + " [implicit deref " + i + " in state " + state + "]" }
349+
override string toString() { result = e + " [implicit deref " + i + " in state " + state + "]" }
350350
}
351351

352352
final class ImplicitDerefArgNode extends ImplicitDerefNode, ArgumentNode {
@@ -356,12 +356,12 @@ final class ImplicitDerefArgNode extends ImplicitDerefNode, ArgumentNode {
356356
ImplicitDerefArgNode() {
357357
not derefChain.isBuiltinDeref(i) and
358358
state = TImplicitDerefNodeAfterBorrowState() and
359-
call_.isImplicitDerefCall(n, derefChain, i, _) and
359+
call_.isImplicitDerefCall(e, derefChain, i, _) and
360360
pos_.isSelf()
361361
or
362362
this.isLast(_) and
363-
TypeInference::implicitDerefChainBorrow(n, derefChain, false) and
364-
isArgumentForCall(n, call_.asCall(), pos_)
363+
TypeInference::implicitDerefChainBorrow(e, derefChain, false) and
364+
isArgumentForCall(e, call_.asCall(), pos_)
365365
}
366366

367367
override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
@@ -378,7 +378,7 @@ private class ImplicitDerefOutNode extends ImplicitDerefNode, OutNode {
378378
}
379379

380380
override DataFlowCall getCall(ReturnKind kind) {
381-
result.isImplicitDerefCall(n, derefChain, i, _) and
381+
result.isImplicitDerefCall(e, derefChain, i, _) and
382382
kind = TNormalReturnKind()
383383
}
384384
}
@@ -387,30 +387,30 @@ private class ImplicitDerefOutNode extends ImplicitDerefNode, OutNode {
387387
* A node that represents the value of an expression _after_ implicit borrowing.
388388
*/
389389
class ImplicitBorrowNode extends ImplicitDerefBorrowNode, TImplicitBorrowNode {
390-
AstNode n;
390+
Expr e;
391391
DerefChain derefChain;
392392

393-
ImplicitBorrowNode() { this = TImplicitBorrowNode(n, derefChain, false) }
393+
ImplicitBorrowNode() { this = TImplicitBorrowNode(e, derefChain, false) }
394394

395-
override AstNode getUnderlyingAstNode() { result = n }
395+
override Expr getExpr() { result = e }
396396

397397
override Node getBorrowInputNode() {
398398
result =
399-
TImplicitDerefNode(n, derefChain, TImplicitDerefNodeAfterDerefState(),
399+
TImplicitDerefNode(e, derefChain, TImplicitDerefNodeAfterDerefState(),
400400
derefChain.length() - 1, false)
401401
or
402402
derefChain.isEmpty() and
403-
result.(AstNodeNode).getAstNode() = n
403+
result.(AstNodeNode).getAstNode() = e
404404
}
405405

406-
override string toString() { result = n + " [implicit borrow]" }
406+
override string toString() { result = e + " [implicit borrow]" }
407407
}
408408

409409
final class ImplicitBorrowArgNode extends ImplicitBorrowNode, ArgumentNode {
410410
private DataFlowCall call_;
411411
private RustDataFlow::ArgumentPosition pos_;
412412

413-
ImplicitBorrowArgNode() { isArgumentForCall(n, call_.asCall(), pos_) }
413+
ImplicitBorrowArgNode() { isArgumentForCall(e, call_.asCall(), pos_) }
414414

415415
override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
416416
call = call_ and pos = pos_
@@ -736,13 +736,15 @@ newtype TNode =
736736
)
737737
} or
738738
TImplicitDerefNode(
739-
AstNode n, DerefChain derefChain, ImplicitDerefNodeState state, int i, Boolean isPost
739+
Expr e, DerefChain derefChain, ImplicitDerefNodeState state, int i, Boolean isPost
740740
) {
741-
TypeInference::implicitDerefChainBorrow(n, derefChain, _) and
741+
e.hasEnclosingCfgScope() and
742+
TypeInference::implicitDerefChainBorrow(e, derefChain, _) and
742743
i in [0 .. derefChain.length() - 1]
743744
} or
744-
TImplicitBorrowNode(AstNode n, DerefChain derefChain, Boolean isPost) {
745-
TypeInference::implicitDerefChainBorrow(n, derefChain, true)
745+
TImplicitBorrowNode(Expr e, DerefChain derefChain, Boolean isPost) {
746+
e.hasEnclosingCfgScope() and
747+
TypeInference::implicitDerefChainBorrow(e, derefChain, true)
746748
} or
747749
TDerefOutNode(DerefExpr de, Boolean isPost) or
748750
TIndexOutNode(IndexExpr ie, Boolean isPost) or

0 commit comments

Comments
 (0)