Skip to content

Commit 42d1256

Browse files
committed
Rust: Value flow through macro calls
1 parent f09632d commit 42d1256

File tree

7 files changed

+27
-19
lines changed

7 files changed

+27
-19
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ final class MethodCallExprCfgNode extends CallExprBaseCfgNode, Nodes::MethodCall
173173
*/
174174
final class CallExprCfgNode extends CallExprBaseCfgNode, Nodes::CallExprCfgNode { }
175175

176+
final class MacroCallCfgNode extends Nodes::MacroCallCfgNode {
177+
private MacroCallChildMapping node;
178+
179+
MacroCallCfgNode() { node = this.getAstNode() }
180+
181+
CfgNode getExpandedNode() {
182+
any(ChildMapping mapping).hasCfgChild(node, node.getExpanded(), this, result)
183+
}
184+
}
185+
176186
/**
177187
* A record expression. For example:
178188
* ```rust

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ class RecordPatChildMapping extends ParentAstNode, RecordPat {
7474
}
7575
}
7676

77+
class MacroCallChildMapping extends ParentAstNode, MacroCall {
78+
override predicate relevantChild(AstNode child) { child = this.getExpanded() }
79+
}
80+
7781
class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree {
7882
override predicate relevantChild(AstNode child) { child = this.getChildNode(_) }
7983
}

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

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,24 +131,8 @@ class LetStmtTree extends PreOrderTree, LetStmt {
131131
}
132132
}
133133

134-
class MacroCallTree extends ControlFlowTree, MacroCall {
135-
override predicate first(AstNode first) {
136-
first(this.getExpanded(), first)
137-
or
138-
not exists(this.getExpanded()) and first = this
139-
}
140-
141-
override predicate last(AstNode last, Completion c) {
142-
last(this.getExpanded(), last, c)
143-
or
144-
not exists(this.getExpanded()) and
145-
last = this and
146-
completionIsValidFor(c, last)
147-
}
148-
149-
override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
150-
151-
override predicate propagatesAbnormal(AstNode child) { child = this.getExpanded() }
134+
class MacroCallTree extends StandardPostOrderTree, MacroCall {
135+
override AstNode getChildNode(int i) { i = 0 and result = this.getExpanded() }
152136
}
153137

154138
class MacroStmtsTree extends StandardPreOrderTree, MacroStmts {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ private ExprCfgNode getALastEvalNode(ExprCfgNode e) {
522522
result = e.(BreakExprCfgNode).getExpr() or
523523
result = e.(BlockExprCfgNode).getTailExpr() or
524524
result = e.(MatchExprCfgNode).getArmExpr(_) or
525+
result = e.(MacroExprCfgNode).getMacroCall().(MacroCallCfgNode).getExpandedNode() or
525526
result.(BreakExprCfgNode).getTarget() = e
526527
}
527528

rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ localStep
66
| main.rs:7:9:7:9 | [SSA] s | main.rs:8:20:8:20 | s |
77
| main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s |
88
| main.rs:7:9:7:14 | ...: i64 | main.rs:7:9:7:9 | s |
9+
| main.rs:8:14:8:20 | FormatArgsExpr | main.rs:8:14:8:20 | MacroExpr |
910
| main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s |
1011
| main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s |
1112
| main.rs:19:13:19:21 | source(...) | main.rs:19:9:19:9 | s |
@@ -459,7 +460,9 @@ localStep
459460
| main.rs:410:9:410:9 | [SSA] s | main.rs:411:10:411:10 | s |
460461
| main.rs:410:9:410:9 | s | main.rs:410:9:410:9 | [SSA] s |
461462
| main.rs:410:13:410:27 | MacroExpr | main.rs:410:9:410:9 | s |
463+
| main.rs:410:25:410:26 | source(...) | main.rs:410:13:410:27 | MacroExpr |
462464
| main.rs:436:13:436:33 | result_questionmark(...) | main.rs:436:9:436:9 | _ |
465+
| main.rs:448:36:448:41 | ...::new(...) | main.rs:448:36:448:41 | MacroExpr |
463466
storeStep
464467
| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::blocking::response::Response>::text |
465468
| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr |

rust/ql/test/library-tests/dataflow/local/inline-flow.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ edges
152152
| main.rs:385:13:385:19 | mut_arr [array[]] | main.rs:385:13:385:22 | mut_arr[1] | provenance | |
153153
| main.rs:385:13:385:22 | mut_arr[1] | main.rs:385:9:385:9 | d | provenance | |
154154
| main.rs:387:10:387:16 | mut_arr [array[]] | main.rs:387:10:387:19 | mut_arr[0] | provenance | |
155+
| main.rs:410:9:410:9 | s | main.rs:411:10:411:10 | s | provenance | |
156+
| main.rs:410:25:410:26 | source(...) | main.rs:410:9:410:9 | s | provenance | |
155157
nodes
156158
| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) |
157159
| main.rs:19:9:19:9 | s | semmle.label | s |
@@ -330,6 +332,9 @@ nodes
330332
| main.rs:386:10:386:10 | d | semmle.label | d |
331333
| main.rs:387:10:387:16 | mut_arr [array[]] | semmle.label | mut_arr [array[]] |
332334
| main.rs:387:10:387:19 | mut_arr[0] | semmle.label | mut_arr[0] |
335+
| main.rs:410:9:410:9 | s | semmle.label | s |
336+
| main.rs:410:25:410:26 | source(...) | semmle.label | source(...) |
337+
| main.rs:411:10:411:10 | s | semmle.label | s |
333338
subpaths
334339
testFailures
335340
#select
@@ -368,3 +373,4 @@ testFailures
368373
| main.rs:375:18:375:18 | c | main.rs:370:23:370:32 | source(...) | main.rs:375:18:375:18 | c | $@ | main.rs:370:23:370:32 | source(...) | source(...) |
369374
| main.rs:386:10:386:10 | d | main.rs:384:18:384:27 | source(...) | main.rs:386:10:386:10 | d | $@ | main.rs:384:18:384:27 | source(...) | source(...) |
370375
| main.rs:387:10:387:19 | mut_arr[0] | main.rs:384:18:384:27 | source(...) | main.rs:387:10:387:19 | mut_arr[0] | $@ | main.rs:384:18:384:27 | source(...) | source(...) |
376+
| main.rs:411:10:411:10 | s | main.rs:410:25:410:26 | source(...) | main.rs:411:10:411:10 | s | $@ | main.rs:410:25:410:26 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/local/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ macro_rules! get_source {
408408

409409
fn macro_invocation() {
410410
let s = get_source!(37);
411-
sink(s); // $ MISSING: hasValueFlow=37
411+
sink(s); // $ hasValueFlow=37
412412
}
413413

414414
fn main() {

0 commit comments

Comments
 (0)