Skip to content

Commit

Permalink
Merge pull request #18314 from paldepind/rust-tuple-ref-patterns
Browse files Browse the repository at this point in the history
Rust: Add read steps for tuple and reference patterns
  • Loading branch information
paldepind authored Dec 18, 2024
2 parents be939dc + 09fd27a commit 508c7e6
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 26 deletions.
9 changes: 9 additions & 0 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,12 @@ module RustDataFlow implements InputSig<Location> {
node2.asPat() = pat.getField(pos)
)
or
exists(TuplePatCfgNode pat, int pos |
pos = c.(TuplePositionContent).getPosition() and
node1.asPat() = pat and
node2.asPat() = pat.getField(pos)
)
or
exists(RecordPatCfgNode pat, string field |
pat = node1.asPat() and
(
Expand All @@ -1023,6 +1029,9 @@ module RustDataFlow implements InputSig<Location> {
node2.asPat() = pat.getFieldPat(field)
)
or
c instanceof ReferenceContent and
node1.asPat().(RefPatCfgNode).getPat() = node2.asPat()
or
exists(FieldExprCfgNode access |
// Read of a tuple entry
fieldTuplePositionContent(access, c) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ readStep
| main.rs:87:11:87:11 | i | &ref | main.rs:87:10:87:11 | * ... |
| main.rs:95:10:95:10 | a | tuple.0 | main.rs:95:10:95:12 | a.0 |
| main.rs:96:10:96:10 | a | tuple.1 | main.rs:96:10:96:12 | a.1 |
| main.rs:101:9:101:20 | TuplePat | tuple.0 | main.rs:101:10:101:11 | a0 |
| main.rs:101:9:101:20 | TuplePat | tuple.1 | main.rs:101:14:101:15 | a1 |
| main.rs:101:9:101:20 | TuplePat | tuple.2 | main.rs:101:18:101:19 | a2 |
| main.rs:109:10:109:10 | a | tuple.0 | main.rs:109:10:109:12 | a.0 |
| main.rs:110:10:110:10 | a | tuple.1 | main.rs:110:10:110:12 | a.1 |
| main.rs:111:5:111:5 | a | tuple.0 | main.rs:111:5:111:7 | a.0 |
Expand Down Expand Up @@ -603,6 +606,8 @@ readStep
| main.rs:384:5:384:11 | mut_arr | array[] | main.rs:384:5:384:14 | mut_arr[1] |
| main.rs:385:13:385:19 | mut_arr | array[] | main.rs:385:13:385:22 | mut_arr[1] |
| main.rs:387:10:387:16 | mut_arr | array[] | main.rs:387:10:387:19 | mut_arr[0] |
| main.rs:394:7:394:18 | TuplePat | tuple.0 | main.rs:394:8:394:11 | cond |
| main.rs:394:7:394:18 | TuplePat | tuple.1 | main.rs:394:14:394:17 | name |
| main.rs:394:23:394:27 | names | array[] | main.rs:394:7:394:18 | TuplePat |
| main.rs:396:35:396:61 | [post] \|...\| ... | captured default_name | main.rs:396:35:396:61 | [post] default_name |
| main.rs:396:38:396:49 | this | captured default_name | main.rs:396:38:396:49 | default_name |
12 changes: 12 additions & 0 deletions rust/ql/test/library-tests/dataflow/local/inline-flow.expected
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ edges
| main.rs:94:13:94:26 | TupleExpr [tuple.0] | main.rs:94:9:94:9 | a [tuple.0] | provenance | |
| main.rs:94:14:94:22 | source(...) | main.rs:94:13:94:26 | TupleExpr [tuple.0] | provenance | |
| main.rs:95:10:95:10 | a [tuple.0] | main.rs:95:10:95:12 | a.0 | provenance | |
| main.rs:100:9:100:9 | a [tuple.1] | main.rs:101:9:101:20 | TuplePat [tuple.1] | provenance | |
| main.rs:100:13:100:30 | TupleExpr [tuple.1] | main.rs:100:9:100:9 | a [tuple.1] | provenance | |
| main.rs:100:17:100:26 | source(...) | main.rs:100:13:100:30 | TupleExpr [tuple.1] | provenance | |
| main.rs:101:9:101:20 | TuplePat [tuple.1] | main.rs:101:14:101:15 | a1 | provenance | |
| main.rs:101:14:101:15 | a1 | main.rs:103:10:103:11 | a1 | provenance | |
| main.rs:108:9:108:13 | a [tuple.1] | main.rs:110:10:110:10 | a [tuple.1] | provenance | |
| main.rs:108:17:108:31 | TupleExpr [tuple.1] | main.rs:108:9:108:13 | a [tuple.1] | provenance | |
| main.rs:108:21:108:30 | source(...) | main.rs:108:17:108:31 | TupleExpr [tuple.1] | provenance | |
Expand Down Expand Up @@ -171,6 +176,12 @@ nodes
| main.rs:94:14:94:22 | source(...) | semmle.label | source(...) |
| main.rs:95:10:95:10 | a [tuple.0] | semmle.label | a [tuple.0] |
| main.rs:95:10:95:12 | a.0 | semmle.label | a.0 |
| main.rs:100:9:100:9 | a [tuple.1] | semmle.label | a [tuple.1] |
| main.rs:100:13:100:30 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
| main.rs:100:17:100:26 | source(...) | semmle.label | source(...) |
| main.rs:101:9:101:20 | TuplePat [tuple.1] | semmle.label | TuplePat [tuple.1] |
| main.rs:101:14:101:15 | a1 | semmle.label | a1 |
| main.rs:103:10:103:11 | a1 | semmle.label | a1 |
| main.rs:108:9:108:13 | a [tuple.1] | semmle.label | a [tuple.1] |
| main.rs:108:17:108:31 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
| main.rs:108:21:108:30 | source(...) | semmle.label | source(...) |
Expand Down Expand Up @@ -329,6 +340,7 @@ testFailures
| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) |
| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) |
| main.rs:95:10:95:12 | a.0 | main.rs:94:14:94:22 | source(...) | main.rs:95:10:95:12 | a.0 | $@ | main.rs:94:14:94:22 | source(...) | source(...) |
| main.rs:103:10:103:11 | a1 | main.rs:100:17:100:26 | source(...) | main.rs:103:10:103:11 | a1 | $@ | main.rs:100:17:100:26 | source(...) | source(...) |
| main.rs:110:10:110:12 | a.1 | main.rs:108:21:108:30 | source(...) | main.rs:110:10:110:12 | a.1 | $@ | main.rs:108:21:108:30 | source(...) | source(...) |
| main.rs:113:10:113:12 | a.0 | main.rs:111:11:111:20 | source(...) | main.rs:113:10:113:12 | a.0 | $@ | main.rs:111:11:111:20 | source(...) | source(...) |
| main.rs:121:10:121:15 | ... .1 | main.rs:118:17:118:26 | source(...) | main.rs:121:10:121:15 | ... .1 | $@ | main.rs:118:17:118:26 | source(...) | source(...) |
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/test/library-tests/dataflow/local/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fn tuple_match() {
let a = (2, source(38), 2);
let (a0, a1, a2) = a;
sink(a0);
sink(a1); // $ MISSING: hasValueFlow=38
sink(a1); // $ hasValueFlow=38
sink(a2);
}

Expand Down
103 changes: 82 additions & 21 deletions rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,42 @@ edges
| main.rs:15:9:15:9 | c | main.rs:16:10:16:10 | c | provenance | |
| main.rs:15:13:15:14 | * ... | main.rs:15:9:15:9 | c | provenance | |
| main.rs:15:14:15:14 | b [&ref] | main.rs:15:13:15:14 | * ... | provenance | |
| main.rs:40:18:40:21 | SelfParam [MyNumber] | main.rs:41:15:41:18 | self [MyNumber] | provenance | |
| main.rs:41:15:41:18 | self [MyNumber] | main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | main.rs:42:32:42:37 | number | provenance | |
| main.rs:42:32:42:37 | number | main.rs:40:31:46:5 | { ... } | provenance | |
| main.rs:58:9:58:17 | my_number [MyNumber] | main.rs:59:10:59:18 | my_number [MyNumber] | provenance | |
| main.rs:58:21:58:50 | ...::MyNumber(...) [MyNumber] | main.rs:58:9:58:17 | my_number [MyNumber] | provenance | |
| main.rs:58:40:58:49 | source(...) | main.rs:58:21:58:50 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:40:18:40:21 | SelfParam [MyNumber] | provenance | |
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:59:10:59:30 | my_number.to_number(...) | provenance | |
| main.rs:35:25:35:26 | &... [&ref] | main.rs:35:26:35:26 | n | provenance | |
| main.rs:35:25:35:32 | ...: ... [&ref] | main.rs:35:25:35:26 | &... [&ref] | provenance | |
| main.rs:35:26:35:26 | n | main.rs:36:10:36:10 | n | provenance | |
| main.rs:40:9:40:11 | val | main.rs:41:27:41:29 | val | provenance | |
| main.rs:40:15:40:24 | source(...) | main.rs:40:9:40:11 | val | provenance | |
| main.rs:41:26:41:29 | &val [&ref] | main.rs:35:25:35:32 | ...: ... [&ref] | provenance | |
| main.rs:41:27:41:29 | val | main.rs:41:26:41:29 | &val [&ref] | provenance | |
| main.rs:49:18:49:21 | SelfParam [MyNumber] | main.rs:50:15:50:18 | self [MyNumber] | provenance | |
| main.rs:50:15:50:18 | self [MyNumber] | main.rs:51:13:51:38 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:51:13:51:38 | ...::MyNumber(...) [MyNumber] | main.rs:51:32:51:37 | number | provenance | |
| main.rs:51:32:51:37 | number | main.rs:49:31:55:5 | { ... } | provenance | |
| main.rs:57:19:57:23 | SelfParam [&ref, MyNumber] | main.rs:58:15:58:18 | self [&ref, MyNumber] | provenance | |
| main.rs:58:15:58:18 | self [&ref, MyNumber] | main.rs:59:13:59:39 | &... [&ref, MyNumber] | provenance | |
| main.rs:59:13:59:39 | &... [&ref, MyNumber] | main.rs:59:14:59:39 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:59:14:59:39 | ...::MyNumber(...) [MyNumber] | main.rs:59:33:59:38 | number | provenance | |
| main.rs:59:33:59:38 | number | main.rs:57:33:63:5 | { ... } | provenance | |
| main.rs:67:9:67:17 | my_number [MyNumber] | main.rs:68:10:68:18 | my_number [MyNumber] | provenance | |
| main.rs:67:21:67:50 | ...::MyNumber(...) [MyNumber] | main.rs:67:9:67:17 | my_number [MyNumber] | provenance | |
| main.rs:67:40:67:49 | source(...) | main.rs:67:21:67:50 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:68:10:68:18 | my_number [MyNumber] | main.rs:49:18:49:21 | SelfParam [MyNumber] | provenance | |
| main.rs:68:10:68:18 | my_number [MyNumber] | main.rs:68:10:68:30 | my_number.to_number(...) | provenance | |
| main.rs:77:9:77:17 | my_number [&ref, MyNumber] | main.rs:78:10:78:18 | my_number [&ref, MyNumber] | provenance | |
| main.rs:77:21:77:51 | &... [&ref, MyNumber] | main.rs:77:9:77:17 | my_number [&ref, MyNumber] | provenance | |
| main.rs:77:22:77:51 | ...::MyNumber(...) [MyNumber] | main.rs:77:21:77:51 | &... [&ref, MyNumber] | provenance | |
| main.rs:77:41:77:50 | source(...) | main.rs:77:22:77:51 | ...::MyNumber(...) [MyNumber] | provenance | |
| main.rs:78:10:78:18 | my_number [&ref, MyNumber] | main.rs:57:19:57:23 | SelfParam [&ref, MyNumber] | provenance | |
| main.rs:78:10:78:18 | my_number [&ref, MyNumber] | main.rs:78:10:78:31 | my_number.get_number(...) | provenance | |
| main.rs:82:9:82:9 | a [&ref, tuple.0] | main.rs:85:19:85:19 | a [&ref, tuple.0] | provenance | |
| main.rs:82:13:82:28 | &... [&ref, tuple.0] | main.rs:82:9:82:9 | a [&ref, tuple.0] | provenance | |
| main.rs:82:14:82:28 | TupleExpr [tuple.0] | main.rs:82:13:82:28 | &... [&ref, tuple.0] | provenance | |
| main.rs:82:15:82:24 | source(...) | main.rs:82:14:82:28 | TupleExpr [tuple.0] | provenance | |
| main.rs:85:9:85:9 | b | main.rs:88:10:88:10 | b | provenance | |
| main.rs:85:19:85:19 | a [&ref, tuple.0] | main.rs:86:9:86:15 | &... [&ref, tuple.0] | provenance | |
| main.rs:86:9:86:15 | &... [&ref, tuple.0] | main.rs:86:10:86:15 | TuplePat [tuple.0] | provenance | |
| main.rs:86:10:86:15 | TuplePat [tuple.0] | main.rs:86:11:86:11 | n | provenance | |
| main.rs:86:11:86:11 | n | main.rs:85:9:85:9 | b | provenance | |
nodes
| main.rs:13:9:13:9 | a | semmle.label | a |
| main.rs:13:13:13:22 | source(...) | semmle.label | source(...) |
Expand All @@ -27,19 +54,53 @@ nodes
| main.rs:15:13:15:14 | * ... | semmle.label | * ... |
| main.rs:15:14:15:14 | b [&ref] | semmle.label | b [&ref] |
| main.rs:16:10:16:10 | c | semmle.label | c |
| main.rs:40:18:40:21 | SelfParam [MyNumber] | semmle.label | SelfParam [MyNumber] |
| main.rs:40:31:46:5 | { ... } | semmle.label | { ... } |
| main.rs:41:15:41:18 | self [MyNumber] | semmle.label | self [MyNumber] |
| main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:42:32:42:37 | number | semmle.label | number |
| main.rs:58:9:58:17 | my_number [MyNumber] | semmle.label | my_number [MyNumber] |
| main.rs:58:21:58:50 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:58:40:58:49 | source(...) | semmle.label | source(...) |
| main.rs:59:10:59:18 | my_number [MyNumber] | semmle.label | my_number [MyNumber] |
| main.rs:59:10:59:30 | my_number.to_number(...) | semmle.label | my_number.to_number(...) |
| main.rs:35:25:35:26 | &... [&ref] | semmle.label | &... [&ref] |
| main.rs:35:25:35:32 | ...: ... [&ref] | semmle.label | ...: ... [&ref] |
| main.rs:35:26:35:26 | n | semmle.label | n |
| main.rs:36:10:36:10 | n | semmle.label | n |
| main.rs:40:9:40:11 | val | semmle.label | val |
| main.rs:40:15:40:24 | source(...) | semmle.label | source(...) |
| main.rs:41:26:41:29 | &val [&ref] | semmle.label | &val [&ref] |
| main.rs:41:27:41:29 | val | semmle.label | val |
| main.rs:49:18:49:21 | SelfParam [MyNumber] | semmle.label | SelfParam [MyNumber] |
| main.rs:49:31:55:5 | { ... } | semmle.label | { ... } |
| main.rs:50:15:50:18 | self [MyNumber] | semmle.label | self [MyNumber] |
| main.rs:51:13:51:38 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:51:32:51:37 | number | semmle.label | number |
| main.rs:57:19:57:23 | SelfParam [&ref, MyNumber] | semmle.label | SelfParam [&ref, MyNumber] |
| main.rs:57:33:63:5 | { ... } | semmle.label | { ... } |
| main.rs:58:15:58:18 | self [&ref, MyNumber] | semmle.label | self [&ref, MyNumber] |
| main.rs:59:13:59:39 | &... [&ref, MyNumber] | semmle.label | &... [&ref, MyNumber] |
| main.rs:59:14:59:39 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:59:33:59:38 | number | semmle.label | number |
| main.rs:67:9:67:17 | my_number [MyNumber] | semmle.label | my_number [MyNumber] |
| main.rs:67:21:67:50 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:67:40:67:49 | source(...) | semmle.label | source(...) |
| main.rs:68:10:68:18 | my_number [MyNumber] | semmle.label | my_number [MyNumber] |
| main.rs:68:10:68:30 | my_number.to_number(...) | semmle.label | my_number.to_number(...) |
| main.rs:77:9:77:17 | my_number [&ref, MyNumber] | semmle.label | my_number [&ref, MyNumber] |
| main.rs:77:21:77:51 | &... [&ref, MyNumber] | semmle.label | &... [&ref, MyNumber] |
| main.rs:77:22:77:51 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
| main.rs:77:41:77:50 | source(...) | semmle.label | source(...) |
| main.rs:78:10:78:18 | my_number [&ref, MyNumber] | semmle.label | my_number [&ref, MyNumber] |
| main.rs:78:10:78:31 | my_number.get_number(...) | semmle.label | my_number.get_number(...) |
| main.rs:82:9:82:9 | a [&ref, tuple.0] | semmle.label | a [&ref, tuple.0] |
| main.rs:82:13:82:28 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
| main.rs:82:14:82:28 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| main.rs:82:15:82:24 | source(...) | semmle.label | source(...) |
| main.rs:85:9:85:9 | b | semmle.label | b |
| main.rs:85:19:85:19 | a [&ref, tuple.0] | semmle.label | a [&ref, tuple.0] |
| main.rs:86:9:86:15 | &... [&ref, tuple.0] | semmle.label | &... [&ref, tuple.0] |
| main.rs:86:10:86:15 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] |
| main.rs:86:11:86:11 | n | semmle.label | n |
| main.rs:88:10:88:10 | b | semmle.label | b |
subpaths
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:40:18:40:21 | SelfParam [MyNumber] | main.rs:40:31:46:5 | { ... } | main.rs:59:10:59:30 | my_number.to_number(...) |
| main.rs:68:10:68:18 | my_number [MyNumber] | main.rs:49:18:49:21 | SelfParam [MyNumber] | main.rs:49:31:55:5 | { ... } | main.rs:68:10:68:30 | my_number.to_number(...) |
| main.rs:78:10:78:18 | my_number [&ref, MyNumber] | main.rs:57:19:57:23 | SelfParam [&ref, MyNumber] | main.rs:57:33:63:5 | { ... } | main.rs:78:10:78:31 | my_number.get_number(...) |
testFailures
#select
| main.rs:16:10:16:10 | c | main.rs:13:13:13:22 | source(...) | main.rs:16:10:16:10 | c | $@ | main.rs:13:13:13:22 | source(...) | source(...) |
| main.rs:59:10:59:30 | my_number.to_number(...) | main.rs:58:40:58:49 | source(...) | main.rs:59:10:59:30 | my_number.to_number(...) | $@ | main.rs:58:40:58:49 | source(...) | source(...) |
| main.rs:36:10:36:10 | n | main.rs:40:15:40:24 | source(...) | main.rs:36:10:36:10 | n | $@ | main.rs:40:15:40:24 | source(...) | source(...) |
| main.rs:68:10:68:30 | my_number.to_number(...) | main.rs:67:40:67:49 | source(...) | main.rs:68:10:68:30 | my_number.to_number(...) | $@ | main.rs:67:40:67:49 | source(...) | source(...) |
| main.rs:78:10:78:31 | my_number.get_number(...) | main.rs:77:41:77:50 | source(...) | main.rs:78:10:78:31 | my_number.get_number(...) | $@ | main.rs:77:41:77:50 | source(...) | source(...) |
| main.rs:88:10:88:10 | b | main.rs:82:15:82:24 | source(...) | main.rs:88:10:88:10 | b | $@ | main.rs:82:15:82:24 | source(...) | source(...) |
39 changes: 35 additions & 4 deletions rust/ql/test/library-tests/dataflow/pointers/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// -----------------------------------------------------------------------------
// Data flow through pointers.
// Data flow through borrows and pointers.

fn source(i: i64) -> i64 {
1000 + i
Expand Down Expand Up @@ -32,6 +32,15 @@ fn write_and_read_through_borrow() {
sink(*b); // $ MISSING: hasValueFlow=37
}

fn takes_borrowed_value(&n: &i64) {
sink(n); // $ hasValueFlow=83
}

fn pass_borrowed_value() {
let val = source(83);
takes_borrowed_value(&val);
}

enum MyNumber {
MyNumber(i64)
}
Expand All @@ -47,8 +56,8 @@ impl MyNumber {

fn get_number(&self) -> i64 {
match self {
MyNumber::MyNumber(number) => {
*number
&MyNumber::MyNumber(number) => {
number
}
}
}
Expand All @@ -66,14 +75,36 @@ fn through_self_in_method_implicit_borrow() {

fn through_self_in_method_explicit_borrow() {
let my_number = &MyNumber::MyNumber(source(40));
sink(my_number.get_number()); // $ MISSING: hasValueFlow=40
sink(my_number.get_number()); // $ hasValueFlow=40
}

fn ref_nested_pattern_match() {
let a = &(source(23), 1);

// Match "in order", ref then tuple
let b = match a {
&(n, _) => n
};
sink(b); // $ hasValueFlow=23

// Match "out of order", tuple then ref
let c = match a {
(n, _) => {
match n {
&i => i
}
}
};
sink(c); // $ MISSING: hasValueFlow=23
}

fn main() {
read_through_borrow();
write_through_borrow();
write_and_read_through_borrow();
pass_borrowed_value();
through_self_in_method_no_borrow();
through_self_in_method_implicit_borrow();
through_self_in_method_explicit_borrow();
ref_nested_pattern_match();
}

0 comments on commit 508c7e6

Please sign in to comment.