Skip to content

Commit 2a68e19

Browse files
committed
Rust: Use canonical paths for variants in data flow
1 parent e6e4f92 commit 2a68e19

File tree

6 files changed

+90
-25
lines changed

6 files changed

+90
-25
lines changed

rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ private module Summaries {
1313
UnwrapSummary() { this = "lang:core::_::<crate::option::Option>::unwrap" }
1414

1515
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
16-
input = "Argument[self].Variant[crate::std::option::Option::Some(0)]" and
16+
input = "Argument[self].Variant[crate::option::Option::Some(0)]" and
1717
output = "ReturnValue" and
1818
preservesValue = true
1919
}

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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -777,15 +777,13 @@ module RustDataFlow implements InputSig<Location> {
777777
exists(CrateOriginOption crate, string path |
778778
resolveExtendedCanonicalPath(p.getQualifier(), crate, path) and
779779
v = MkVariantCanonicalPath(crate, path, p.getPart().getNameRef().getText())
780+
or
781+
exists(string name |
782+
not p.hasQualifier() and
783+
resolveExtendedCanonicalPath(p, crate, path + "::" + name) and
784+
v = MkVariantCanonicalPath(crate, path, name)
785+
)
780786
)
781-
or
782-
// TODO: Remove once library types are extracted
783-
not p.hasQualifier() and
784-
v = MkVariantCanonicalPath(_, "crate::std::option::Option", p.getPart().getNameRef().getText())
785-
or
786-
// TODO: Remove once library types are extracted
787-
not p.hasQualifier() and
788-
v = MkVariantCanonicalPath(_, "crate::std::result::Result", p.getPart().getNameRef().getText())
789787
}
790788

791789
/** Holds if `p` destructs an enum variant `v`. */
@@ -1002,20 +1000,22 @@ private module Cached {
10021000
cached
10031001
newtype TReturnKind = TNormalReturnKind()
10041002

1003+
private CrateOriginOption langCoreCrate() { result.asSome() = "lang:core" }
1004+
10051005
cached
10061006
newtype TVariantCanonicalPath =
10071007
MkVariantCanonicalPath(CrateOriginOption crate, string path, string name) {
10081008
variantHasExtendedCanonicalPath(_, _, crate, path, name)
10091009
or
10101010
// TODO: Remove once library types are extracted
1011-
crate.isNone() and
1012-
path = "crate::std::option::Option" and
1013-
name = "Some"
1014-
or
1015-
// TODO: Remove once library types are extracted
1016-
crate.isNone() and
1017-
path = "crate::std::result::Result" and
1018-
name = ["Ok", "Err"]
1011+
crate = langCoreCrate() and
1012+
(
1013+
path = "crate::option::Option" and
1014+
name = "Some"
1015+
or
1016+
path = "crate::result::Result" and
1017+
name = ["Ok", "Err"]
1018+
)
10191019
}
10201020

10211021
cached
@@ -1024,11 +1024,11 @@ private module Cached {
10241024
pos in [0 .. v.getVariant().getFieldList().(TupleFieldList).getNumberOfFields() - 1]
10251025
or
10261026
// TODO: Remove once library types are extracted
1027-
v = MkVariantCanonicalPath(_, "crate::std::option::Option", "Some") and
1027+
v = MkVariantCanonicalPath(langCoreCrate(), "crate::option::Option", "Some") and
10281028
pos = 0
10291029
or
10301030
// TODO: Remove once library types are extracted
1031-
v = MkVariantCanonicalPath(_, "crate::std::result::Result", ["Ok", "Err"]) and
1031+
v = MkVariantCanonicalPath(langCoreCrate(), "crate::result::Result", ["Ok", "Err"]) and
10321032
pos = 0
10331033
} or
10341034
TVariantFieldContent(VariantCanonicalPath v, string field) {

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,25 @@ localStep
284284
| main.rs:236:22:236:22 | 2 | main.rs:236:9:236:22 | break ''block 2 |
285285
| main.rs:238:5:238:5 | a | main.rs:231:38:239:1 | { ... } |
286286
storeStep
287+
| main.rs:104:27:104:36 | source(...) | Some | main.rs:104:14:104:37 | ...::Some(...) |
288+
| main.rs:105:27:105:27 | 2 | Some | main.rs:105:14:105:28 | ...::Some(...) |
287289
| main.rs:117:19:117:28 | source(...) | Some | main.rs:117:14:117:29 | Some(...) |
288290
| main.rs:118:19:118:19 | 2 | Some | main.rs:118:14:118:20 | Some(...) |
289291
| main.rs:130:19:130:28 | source(...) | Some | main.rs:130:14:130:29 | Some(...) |
290292
| main.rs:140:29:140:38 | source(...) | A | main.rs:140:14:140:39 | ...::A(...) |
291293
| main.rs:141:29:141:29 | 2 | B | main.rs:141:14:141:30 | ...::B(...) |
294+
| main.rs:158:16:158:25 | source(...) | A | main.rs:158:14:158:26 | A(...) |
295+
| main.rs:159:16:159:16 | 2 | B | main.rs:159:14:159:17 | B(...) |
292296
| main.rs:180:18:180:27 | source(...) | C | main.rs:179:14:181:5 | ...::C {...} |
293297
| main.rs:182:41:182:41 | 2 | D | main.rs:182:14:182:43 | ...::D {...} |
298+
| main.rs:200:18:200:27 | source(...) | C | main.rs:199:14:201:5 | C {...} |
299+
| main.rs:202:27:202:27 | 2 | D | main.rs:202:14:202:29 | D {...} |
294300
| main.rs:245:27:245:27 | 0 | Some | main.rs:245:22:245:28 | Some(...) |
295301
readStep
296-
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::std::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap |
302+
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap |
297303
| main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ |
304+
| main.rs:107:9:107:23 | TupleStructPat | Some | main.rs:107:22:107:22 | n |
305+
| main.rs:111:9:111:23 | TupleStructPat | Some | main.rs:111:22:111:22 | n |
298306
| main.rs:120:9:120:15 | TupleStructPat | Some | main.rs:120:14:120:14 | n |
299307
| main.rs:124:9:124:15 | TupleStructPat | Some | main.rs:124:14:124:14 | n |
300308
| main.rs:143:9:143:25 | TupleStructPat | A | main.rs:143:24:143:24 | n |
@@ -303,9 +311,21 @@ readStep
303311
| main.rs:147:30:147:46 | TupleStructPat | B | main.rs:147:45:147:45 | n |
304312
| main.rs:150:9:150:25 | TupleStructPat | A | main.rs:150:24:150:24 | n |
305313
| main.rs:151:9:151:25 | TupleStructPat | B | main.rs:151:24:151:24 | n |
314+
| main.rs:161:9:161:12 | TupleStructPat | A | main.rs:161:11:161:11 | n |
315+
| main.rs:162:9:162:12 | TupleStructPat | B | main.rs:162:11:162:11 | n |
316+
| main.rs:165:10:165:13 | TupleStructPat | A | main.rs:165:12:165:12 | n |
317+
| main.rs:165:17:165:20 | TupleStructPat | B | main.rs:165:19:165:19 | n |
318+
| main.rs:168:9:168:12 | TupleStructPat | A | main.rs:168:11:168:11 | n |
319+
| main.rs:169:9:169:12 | TupleStructPat | B | main.rs:169:11:169:11 | n |
306320
| main.rs:184:9:184:38 | ...::C {...} | C | main.rs:184:36:184:36 | n |
307321
| main.rs:185:9:185:38 | ...::D {...} | D | main.rs:185:36:185:36 | n |
308322
| main.rs:188:10:188:39 | ...::C {...} | C | main.rs:188:37:188:37 | n |
309323
| main.rs:188:43:188:72 | ...::D {...} | D | main.rs:188:70:188:70 | n |
310324
| main.rs:191:9:191:38 | ...::C {...} | C | main.rs:191:36:191:36 | n |
311325
| main.rs:192:9:192:38 | ...::D {...} | D | main.rs:192:36:192:36 | n |
326+
| main.rs:204:9:204:24 | C {...} | C | main.rs:204:22:204:22 | n |
327+
| main.rs:205:9:205:24 | D {...} | D | main.rs:205:22:205:22 | n |
328+
| main.rs:208:10:208:25 | C {...} | C | main.rs:208:23:208:23 | n |
329+
| main.rs:208:29:208:44 | D {...} | D | main.rs:208:42:208:42 | n |
330+
| main.rs:211:9:211:24 | C {...} | C | main.rs:211:22:211:22 | n |
331+
| main.rs:212:9:212:24 | D {...} | D | main.rs:212:22:212:22 | n |

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ edges
55
| main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | |
66
| main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | |
77
| main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | |
8+
| main.rs:104:14:104:37 | ...::Some(...) [Some] | main.rs:107:9:107:23 | TupleStructPat [Some] | provenance | |
9+
| main.rs:104:27:104:36 | source(...) | main.rs:104:14:104:37 | ...::Some(...) [Some] | provenance | |
10+
| main.rs:107:9:107:23 | TupleStructPat [Some] | main.rs:107:22:107:22 | n | provenance | |
11+
| main.rs:107:22:107:22 | n | main.rs:107:33:107:33 | n | provenance | |
812
| main.rs:117:14:117:29 | Some(...) [Some] | main.rs:120:9:120:15 | TupleStructPat [Some] | provenance | |
913
| main.rs:117:19:117:28 | source(...) | main.rs:117:14:117:29 | Some(...) [Some] | provenance | |
1014
| main.rs:120:9:120:15 | TupleStructPat [Some] | main.rs:120:14:120:14 | n | provenance | |
@@ -19,13 +23,27 @@ edges
1923
| main.rs:143:24:143:24 | n | main.rs:143:35:143:35 | n | provenance | |
2024
| main.rs:147:10:147:26 | TupleStructPat [A] | main.rs:147:25:147:25 | n | provenance | |
2125
| main.rs:147:25:147:25 | n | main.rs:147:57:147:57 | n | provenance | |
26+
| main.rs:158:14:158:26 | A(...) [A] | main.rs:161:9:161:12 | TupleStructPat [A] | provenance | |
27+
| main.rs:158:14:158:26 | A(...) [A] | main.rs:165:10:165:13 | TupleStructPat [A] | provenance | |
28+
| main.rs:158:16:158:25 | source(...) | main.rs:158:14:158:26 | A(...) [A] | provenance | |
29+
| main.rs:161:9:161:12 | TupleStructPat [A] | main.rs:161:11:161:11 | n | provenance | |
30+
| main.rs:161:11:161:11 | n | main.rs:161:22:161:22 | n | provenance | |
31+
| main.rs:165:10:165:13 | TupleStructPat [A] | main.rs:165:12:165:12 | n | provenance | |
32+
| main.rs:165:12:165:12 | n | main.rs:165:31:165:31 | n | provenance | |
2233
| main.rs:179:14:181:5 | ...::C {...} [C] | main.rs:184:9:184:38 | ...::C {...} [C] | provenance | |
2334
| main.rs:179:14:181:5 | ...::C {...} [C] | main.rs:188:10:188:39 | ...::C {...} [C] | provenance | |
2435
| main.rs:180:18:180:27 | source(...) | main.rs:179:14:181:5 | ...::C {...} [C] | provenance | |
2536
| main.rs:184:9:184:38 | ...::C {...} [C] | main.rs:184:36:184:36 | n | provenance | |
2637
| main.rs:184:36:184:36 | n | main.rs:184:48:184:48 | n | provenance | |
2738
| main.rs:188:10:188:39 | ...::C {...} [C] | main.rs:188:37:188:37 | n | provenance | |
2839
| main.rs:188:37:188:37 | n | main.rs:188:83:188:83 | n | provenance | |
40+
| main.rs:199:14:201:5 | C {...} [C] | main.rs:204:9:204:24 | C {...} [C] | provenance | |
41+
| main.rs:199:14:201:5 | C {...} [C] | main.rs:208:10:208:25 | C {...} [C] | provenance | |
42+
| main.rs:200:18:200:27 | source(...) | main.rs:199:14:201:5 | C {...} [C] | provenance | |
43+
| main.rs:204:9:204:24 | C {...} [C] | main.rs:204:22:204:22 | n | provenance | |
44+
| main.rs:204:22:204:22 | n | main.rs:204:34:204:34 | n | provenance | |
45+
| main.rs:208:10:208:25 | C {...} [C] | main.rs:208:23:208:23 | n | provenance | |
46+
| main.rs:208:23:208:23 | n | main.rs:208:55:208:55 | n | provenance | |
2947
nodes
3048
| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) |
3149
| main.rs:19:13:19:21 | source(...) | semmle.label | source(...) |
@@ -38,6 +56,11 @@ nodes
3856
| main.rs:47:10:47:10 | b | semmle.label | b |
3957
| main.rs:53:9:53:17 | source(...) | semmle.label | source(...) |
4058
| main.rs:54:10:54:10 | i | semmle.label | i |
59+
| main.rs:104:14:104:37 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] |
60+
| main.rs:104:27:104:36 | source(...) | semmle.label | source(...) |
61+
| main.rs:107:9:107:23 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] |
62+
| main.rs:107:22:107:22 | n | semmle.label | n |
63+
| main.rs:107:33:107:33 | n | semmle.label | n |
4164
| main.rs:117:14:117:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
4265
| main.rs:117:19:117:28 | source(...) | semmle.label | source(...) |
4366
| main.rs:120:9:120:15 | TupleStructPat [Some] | semmle.label | TupleStructPat [Some] |
@@ -55,6 +78,14 @@ nodes
5578
| main.rs:147:10:147:26 | TupleStructPat [A] | semmle.label | TupleStructPat [A] |
5679
| main.rs:147:25:147:25 | n | semmle.label | n |
5780
| main.rs:147:57:147:57 | n | semmle.label | n |
81+
| main.rs:158:14:158:26 | A(...) [A] | semmle.label | A(...) [A] |
82+
| main.rs:158:16:158:25 | source(...) | semmle.label | source(...) |
83+
| main.rs:161:9:161:12 | TupleStructPat [A] | semmle.label | TupleStructPat [A] |
84+
| main.rs:161:11:161:11 | n | semmle.label | n |
85+
| main.rs:161:22:161:22 | n | semmle.label | n |
86+
| main.rs:165:10:165:13 | TupleStructPat [A] | semmle.label | TupleStructPat [A] |
87+
| main.rs:165:12:165:12 | n | semmle.label | n |
88+
| main.rs:165:31:165:31 | n | semmle.label | n |
5889
| main.rs:179:14:181:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
5990
| main.rs:180:18:180:27 | source(...) | semmle.label | source(...) |
6091
| main.rs:184:9:184:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
@@ -63,6 +94,14 @@ nodes
6394
| main.rs:188:10:188:39 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
6495
| main.rs:188:37:188:37 | n | semmle.label | n |
6596
| main.rs:188:83:188:83 | n | semmle.label | n |
97+
| main.rs:199:14:201:5 | C {...} [C] | semmle.label | C {...} [C] |
98+
| main.rs:200:18:200:27 | source(...) | semmle.label | source(...) |
99+
| main.rs:204:9:204:24 | C {...} [C] | semmle.label | C {...} [C] |
100+
| main.rs:204:22:204:22 | n | semmle.label | n |
101+
| main.rs:204:34:204:34 | n | semmle.label | n |
102+
| main.rs:208:10:208:25 | C {...} [C] | semmle.label | C {...} [C] |
103+
| main.rs:208:23:208:23 | n | semmle.label | n |
104+
| main.rs:208:55:208:55 | n | semmle.label | n |
66105
subpaths
67106
testFailures
68107
#select
@@ -72,9 +111,14 @@ testFailures
72111
| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) |
73112
| 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(...) |
74113
| 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(...) |
114+
| main.rs:107:33:107:33 | n | main.rs:104:27:104:36 | source(...) | main.rs:107:33:107:33 | n | $@ | main.rs:104:27:104:36 | source(...) | source(...) |
75115
| main.rs:120:25:120:25 | n | main.rs:117:19:117:28 | source(...) | main.rs:120:25:120:25 | n | $@ | main.rs:117:19:117:28 | source(...) | source(...) |
76116
| main.rs:131:10:131:20 | ... .unwrap(...) | main.rs:130:19:130:28 | source(...) | main.rs:131:10:131:20 | ... .unwrap(...) | $@ | main.rs:130:19:130:28 | source(...) | source(...) |
77117
| main.rs:143:35:143:35 | n | main.rs:140:29:140:38 | source(...) | main.rs:143:35:143:35 | n | $@ | main.rs:140:29:140:38 | source(...) | source(...) |
78118
| main.rs:147:57:147:57 | n | main.rs:140:29:140:38 | source(...) | main.rs:147:57:147:57 | n | $@ | main.rs:140:29:140:38 | source(...) | source(...) |
119+
| main.rs:161:22:161:22 | n | main.rs:158:16:158:25 | source(...) | main.rs:161:22:161:22 | n | $@ | main.rs:158:16:158:25 | source(...) | source(...) |
120+
| main.rs:165:31:165:31 | n | main.rs:158:16:158:25 | source(...) | main.rs:165:31:165:31 | n | $@ | main.rs:158:16:158:25 | source(...) | source(...) |
79121
| main.rs:184:48:184:48 | n | main.rs:180:18:180:27 | source(...) | main.rs:184:48:184:48 | n | $@ | main.rs:180:18:180:27 | source(...) | source(...) |
80122
| main.rs:188:83:188:83 | n | main.rs:180:18:180:27 | source(...) | main.rs:188:83:188:83 | n | $@ | main.rs:180:18:180:27 | source(...) | source(...) |
123+
| main.rs:204:34:204:34 | n | main.rs:200:18:200:27 | source(...) | main.rs:204:34:204:34 | n | $@ | main.rs:200:18:200:27 | source(...) | source(...) |
124+
| main.rs:208:55:208:55 | n | main.rs:200:18:200:27 | source(...) | main.rs:208:55:208:55 | n | $@ | main.rs:200:18:200:27 | source(...) | source(...) |

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn option_pattern_match_qualified() {
104104
let s1 = Option::Some(source(13));
105105
let s2 = Option::Some(2);
106106
match s1 {
107-
Option::Some(n) => sink(n), // $ MISSING: hasValueFlow=13
107+
Option::Some(n) => sink(n), // $ hasValueFlow=13
108108
Option::None => sink(0),
109109
}
110110
match s2 {
@@ -158,11 +158,11 @@ fn custom_tuple_enum_pattern_match_unqualified() {
158158
let s1 = A(source(16));
159159
let s2 = B(2);
160160
match s1 {
161-
A(n) => sink(n), // $ MISSING: hasValueFlow=16
161+
A(n) => sink(n), // $ hasValueFlow=16
162162
B(n) => sink(n),
163163
}
164164
match s1 {
165-
(A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16
165+
(A(n) | B(n)) => sink(n), // $ hasValueFlow=16
166166
}
167167
match s2 {
168168
A(n) => sink(n),
@@ -201,11 +201,11 @@ fn custom_record_enum_pattern_match_unqualified() {
201201
};
202202
let s2 = D { field_d: 2 };
203203
match s1 {
204-
C { field_c: n } => sink(n), // $ MISSING: hasValueFlow=18
204+
C { field_c: n } => sink(n), // $ hasValueFlow=18
205205
D { field_d: n } => sink(n),
206206
}
207207
match s1 {
208-
(C { field_c: n } | D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=18
208+
(C { field_c: n } | D { field_d: n }) => sink(n), // $ hasValueFlow=18
209209
}
210210
match s2 {
211211
C { field_c: n } => sink(n),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,5 @@ fn main() {
8686
test_set_var_pos();
8787
test_get_var_field();
8888
test_set_var_field();
89+
let dummy = Some(0); // ensure that the the `lang:core` crate is extracted
8990
}

0 commit comments

Comments
 (0)