Skip to content

Commit abda28d

Browse files
committed
Rust: Add value flow model for clone methods
1 parent 04d3f98 commit abda28d

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

rust/ql/lib/codeql/rust/Frameworks.qll

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
private import codeql.rust.frameworks.rustcrypto.RustCrypto
66
private import codeql.rust.frameworks.Sqlx
7+
private import codeql.rust.frameworks.stdlib.Clone
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// A model for `clone` on the `Clone` trait
2+
import rust
3+
import codeql.rust.dataflow.FlowSummary
4+
5+
/** A `clone` method. */
6+
final class CloneCallable extends SummarizedCallable::Range {
7+
CloneCallable() {
8+
// NOTE: The function target may not exist in the database, so we base this
9+
// on method calls.
10+
exists(MethodCallExpr c |
11+
c.getNameRef().getText() = "clone" and
12+
c.getArgList().getNumberOfArgs() = 0 and
13+
this = c.getResolvedCrateOrigin() + "::_::" + c.getResolvedPath()
14+
)
15+
}
16+
17+
final override predicate propagatesFlow(string input, string output, boolean preservesValue) {
18+
input = "Argument[self]" and output = "ReturnValue" and preservesValue = true
19+
}
20+
}

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

+46
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,92 @@ models
33
| 2 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value |
44
edges
55
| main.rs:13:9:13:9 | a [Some] | main.rs:14:10:14:10 | a [Some] | provenance | |
6+
| main.rs:13:9:13:9 | a [Some] | main.rs:15:13:15:13 | a [Some] | provenance | |
67
| main.rs:13:13:13:28 | Some(...) [Some] | main.rs:13:9:13:9 | a [Some] | provenance | |
78
| main.rs:13:18:13:27 | source(...) | main.rs:13:13:13:28 | Some(...) [Some] | provenance | |
89
| main.rs:14:10:14:10 | a [Some] | main.rs:14:10:14:19 | a.unwrap(...) | provenance | MaD:1 |
10+
| main.rs:15:9:15:9 | b [Some] | main.rs:16:10:16:10 | b [Some] | provenance | |
11+
| main.rs:15:13:15:13 | a [Some] | main.rs:15:13:15:21 | a.clone(...) [Some] | provenance | |
12+
| main.rs:15:13:15:21 | a.clone(...) [Some] | main.rs:15:9:15:9 | b [Some] | provenance | |
13+
| main.rs:16:10:16:10 | b [Some] | main.rs:16:10:16:19 | b.unwrap(...) | provenance | MaD:1 |
914
| main.rs:20:9:20:9 | a [Ok] | main.rs:21:10:21:10 | a [Ok] | provenance | |
15+
| main.rs:20:9:20:9 | a [Ok] | main.rs:22:13:22:13 | a [Ok] | provenance | |
1016
| main.rs:20:31:20:44 | Ok(...) [Ok] | main.rs:20:9:20:9 | a [Ok] | provenance | |
1117
| main.rs:20:34:20:43 | source(...) | main.rs:20:31:20:44 | Ok(...) [Ok] | provenance | |
1218
| main.rs:21:10:21:10 | a [Ok] | main.rs:21:10:21:19 | a.unwrap(...) | provenance | MaD:2 |
19+
| main.rs:22:9:22:9 | b [Ok] | main.rs:23:10:23:10 | b [Ok] | provenance | |
20+
| main.rs:22:13:22:13 | a [Ok] | main.rs:22:13:22:21 | a.clone(...) [Ok] | provenance | |
21+
| main.rs:22:13:22:21 | a.clone(...) [Ok] | main.rs:22:9:22:9 | b [Ok] | provenance | |
22+
| main.rs:23:10:23:10 | b [Ok] | main.rs:23:10:23:19 | b.unwrap(...) | provenance | MaD:2 |
1323
| main.rs:27:9:27:9 | a | main.rs:28:10:28:10 | a | provenance | |
24+
| main.rs:27:9:27:9 | a | main.rs:29:13:29:13 | a | provenance | |
1425
| main.rs:27:13:27:22 | source(...) | main.rs:27:9:27:9 | a | provenance | |
26+
| main.rs:29:9:29:9 | b | main.rs:30:10:30:10 | b | provenance | |
27+
| main.rs:29:13:29:13 | a | main.rs:29:13:29:21 | a.clone(...) | provenance | |
28+
| main.rs:29:13:29:21 | a.clone(...) | main.rs:29:9:29:9 | b | provenance | |
1529
| main.rs:42:13:42:13 | w [Wrapper.n] | main.rs:43:15:43:15 | w [Wrapper.n] | provenance | |
1630
| main.rs:42:17:42:41 | Wrapper {...} [Wrapper.n] | main.rs:42:13:42:13 | w [Wrapper.n] | provenance | |
1731
| main.rs:42:30:42:39 | source(...) | main.rs:42:17:42:41 | Wrapper {...} [Wrapper.n] | provenance | |
1832
| main.rs:43:15:43:15 | w [Wrapper.n] | main.rs:44:13:44:28 | Wrapper {...} [Wrapper.n] | provenance | |
33+
| main.rs:43:15:43:15 | w [Wrapper.n] | main.rs:46:17:46:17 | w [Wrapper.n] | provenance | |
1934
| main.rs:44:13:44:28 | Wrapper {...} [Wrapper.n] | main.rs:44:26:44:26 | n | provenance | |
2035
| main.rs:44:26:44:26 | n | main.rs:44:38:44:38 | n | provenance | |
36+
| main.rs:46:13:46:13 | u [Wrapper.n] | main.rs:47:15:47:15 | u [Wrapper.n] | provenance | |
37+
| main.rs:46:17:46:17 | w [Wrapper.n] | main.rs:46:17:46:25 | w.clone(...) [Wrapper.n] | provenance | |
38+
| main.rs:46:17:46:25 | w.clone(...) [Wrapper.n] | main.rs:46:13:46:13 | u [Wrapper.n] | provenance | |
39+
| main.rs:47:15:47:15 | u [Wrapper.n] | main.rs:48:13:48:28 | Wrapper {...} [Wrapper.n] | provenance | |
40+
| main.rs:48:13:48:28 | Wrapper {...} [Wrapper.n] | main.rs:48:26:48:26 | n | provenance | |
41+
| main.rs:48:26:48:26 | n | main.rs:48:38:48:38 | n | provenance | |
2142
nodes
2243
| main.rs:13:9:13:9 | a [Some] | semmle.label | a [Some] |
2344
| main.rs:13:13:13:28 | Some(...) [Some] | semmle.label | Some(...) [Some] |
2445
| main.rs:13:18:13:27 | source(...) | semmle.label | source(...) |
2546
| main.rs:14:10:14:10 | a [Some] | semmle.label | a [Some] |
2647
| main.rs:14:10:14:19 | a.unwrap(...) | semmle.label | a.unwrap(...) |
48+
| main.rs:15:9:15:9 | b [Some] | semmle.label | b [Some] |
49+
| main.rs:15:13:15:13 | a [Some] | semmle.label | a [Some] |
50+
| main.rs:15:13:15:21 | a.clone(...) [Some] | semmle.label | a.clone(...) [Some] |
51+
| main.rs:16:10:16:10 | b [Some] | semmle.label | b [Some] |
52+
| main.rs:16:10:16:19 | b.unwrap(...) | semmle.label | b.unwrap(...) |
2753
| main.rs:20:9:20:9 | a [Ok] | semmle.label | a [Ok] |
2854
| main.rs:20:31:20:44 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] |
2955
| main.rs:20:34:20:43 | source(...) | semmle.label | source(...) |
3056
| main.rs:21:10:21:10 | a [Ok] | semmle.label | a [Ok] |
3157
| main.rs:21:10:21:19 | a.unwrap(...) | semmle.label | a.unwrap(...) |
58+
| main.rs:22:9:22:9 | b [Ok] | semmle.label | b [Ok] |
59+
| main.rs:22:13:22:13 | a [Ok] | semmle.label | a [Ok] |
60+
| main.rs:22:13:22:21 | a.clone(...) [Ok] | semmle.label | a.clone(...) [Ok] |
61+
| main.rs:23:10:23:10 | b [Ok] | semmle.label | b [Ok] |
62+
| main.rs:23:10:23:19 | b.unwrap(...) | semmle.label | b.unwrap(...) |
3263
| main.rs:27:9:27:9 | a | semmle.label | a |
3364
| main.rs:27:13:27:22 | source(...) | semmle.label | source(...) |
3465
| main.rs:28:10:28:10 | a | semmle.label | a |
66+
| main.rs:29:9:29:9 | b | semmle.label | b |
67+
| main.rs:29:13:29:13 | a | semmle.label | a |
68+
| main.rs:29:13:29:21 | a.clone(...) | semmle.label | a.clone(...) |
69+
| main.rs:30:10:30:10 | b | semmle.label | b |
3570
| main.rs:42:13:42:13 | w [Wrapper.n] | semmle.label | w [Wrapper.n] |
3671
| main.rs:42:17:42:41 | Wrapper {...} [Wrapper.n] | semmle.label | Wrapper {...} [Wrapper.n] |
3772
| main.rs:42:30:42:39 | source(...) | semmle.label | source(...) |
3873
| main.rs:43:15:43:15 | w [Wrapper.n] | semmle.label | w [Wrapper.n] |
3974
| main.rs:44:13:44:28 | Wrapper {...} [Wrapper.n] | semmle.label | Wrapper {...} [Wrapper.n] |
4075
| main.rs:44:26:44:26 | n | semmle.label | n |
4176
| main.rs:44:38:44:38 | n | semmle.label | n |
77+
| main.rs:46:13:46:13 | u [Wrapper.n] | semmle.label | u [Wrapper.n] |
78+
| main.rs:46:17:46:17 | w [Wrapper.n] | semmle.label | w [Wrapper.n] |
79+
| main.rs:46:17:46:25 | w.clone(...) [Wrapper.n] | semmle.label | w.clone(...) [Wrapper.n] |
80+
| main.rs:47:15:47:15 | u [Wrapper.n] | semmle.label | u [Wrapper.n] |
81+
| main.rs:48:13:48:28 | Wrapper {...} [Wrapper.n] | semmle.label | Wrapper {...} [Wrapper.n] |
82+
| main.rs:48:26:48:26 | n | semmle.label | n |
83+
| main.rs:48:38:48:38 | n | semmle.label | n |
4284
subpaths
4385
testFailures
4486
#select
4587
| main.rs:14:10:14:19 | a.unwrap(...) | main.rs:13:18:13:27 | source(...) | main.rs:14:10:14:19 | a.unwrap(...) | $@ | main.rs:13:18:13:27 | source(...) | source(...) |
88+
| main.rs:16:10:16:19 | b.unwrap(...) | main.rs:13:18:13:27 | source(...) | main.rs:16:10:16:19 | b.unwrap(...) | $@ | main.rs:13:18:13:27 | source(...) | source(...) |
4689
| main.rs:21:10:21:19 | a.unwrap(...) | main.rs:20:34:20:43 | source(...) | main.rs:21:10:21:19 | a.unwrap(...) | $@ | main.rs:20:34:20:43 | source(...) | source(...) |
90+
| main.rs:23:10:23:19 | b.unwrap(...) | main.rs:20:34:20:43 | source(...) | main.rs:23:10:23:19 | b.unwrap(...) | $@ | main.rs:20:34:20:43 | source(...) | source(...) |
4791
| main.rs:28:10:28:10 | a | main.rs:27:13:27:22 | source(...) | main.rs:28:10:28:10 | a | $@ | main.rs:27:13:27:22 | source(...) | source(...) |
92+
| main.rs:30:10:30:10 | b | main.rs:27:13:27:22 | source(...) | main.rs:30:10:30:10 | b | $@ | main.rs:27:13:27:22 | source(...) | source(...) |
4893
| main.rs:44:38:44:38 | n | main.rs:42:30:42:39 | source(...) | main.rs:44:38:44:38 | n | $@ | main.rs:42:30:42:39 | source(...) | source(...) |
94+
| main.rs:48:38:48:38 | n | main.rs:42:30:42:39 | source(...) | main.rs:48:38:48:38 | n | $@ | main.rs:42:30:42:39 | source(...) | source(...) |

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ fn option_clone() {
1313
let a = Some(source(88));
1414
sink(a.unwrap()); // $ hasValueFlow=88
1515
let b = a.clone();
16-
sink(b.unwrap()); // $ MISSING: hasValueFlow=88
16+
sink(b.unwrap()); // $ hasValueFlow=88
1717
}
1818

1919
fn result_clone() {
2020
let a: Result<i64, i64> = Ok(source(37));
2121
sink(a.unwrap()); // $ hasValueFlow=37
2222
let b = a.clone();
23-
sink(b.unwrap()); // $ MISSING: hasValueFlow=37
23+
sink(b.unwrap()); // $ hasValueFlow=37
2424
}
2525

2626
fn i64_clone() {
2727
let a = source(12);
2828
sink(a); // $ hasValueFlow=12
2929
let b = a.clone();
30-
sink(b); // $ MISSING: hasValueFlow=12
30+
sink(b); // $ hasValueFlow=12
3131
}
3232

3333
mod my_clone {
@@ -45,7 +45,7 @@ mod my_clone {
4545
}
4646
let u = w.clone();
4747
match u {
48-
Wrapper { n: n } => sink(n) // $ MISSING: hasValueFlow=73
48+
Wrapper { n: n } => sink(n) // $ hasValueFlow=73
4949
}
5050
}
5151
}

0 commit comments

Comments
 (0)