Skip to content

Commit f406914

Browse files
authored
Merge pull request #18701 from geoffw0/nth
Rust: Test and model some string and iterator methods
2 parents a35510d + 6cb8f65 commit f406914

File tree

13 files changed

+375
-95
lines changed

13 files changed

+375
-95
lines changed

rust/ql/integration-tests/hello-project/summary.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |
1616
| Macro calls - unresolved | 0 |
17-
| Taint edges - number of edges | 4 |
17+
| Taint edges - number of edges | 10 |
1818
| Taint reach - nodes tainted | 0 |
1919
| Taint reach - per million nodes | 0 |
2020
| Taint sinks - cryptographic operations | 0 |

rust/ql/integration-tests/hello-workspace/summary.cargo.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |
1616
| Macro calls - unresolved | 0 |
17-
| Taint edges - number of edges | 4 |
17+
| Taint edges - number of edges | 10 |
1818
| Taint reach - nodes tainted | 0 |
1919
| Taint reach - per million nodes | 0 |
2020
| Taint sinks - cryptographic operations | 0 |

rust/ql/integration-tests/hello-workspace/summary.rust-project.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
| Macro calls - resolved | 2 |
1515
| Macro calls - total | 2 |
1616
| Macro calls - unresolved | 0 |
17-
| Taint edges - number of edges | 4 |
17+
| Taint edges - number of edges | 10 |
1818
| Taint reach - nodes tainted | 0 |
1919
| Taint reach - per million nodes | 0 |
2020
| Taint sinks - cryptographic operations | 0 |

rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml

+14
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,19 @@ extensions:
88
# Hint
99
- ["lang:core", "crate::hint::must_use", "Argument[0]", "ReturnValue", "value", "manual"]
1010
# Iterator
11+
- ["lang:core", "<[_]>::iter", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"]
12+
- ["lang:core", "<[_]>::iter_mut", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"]
13+
- ["lang:core", "<[_]>::into_iter", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"]
1114
- ["lang:core", "crate::iter::traits::iterator::Iterator::nth", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"]
15+
- ["lang:core", "crate::iter::traits::iterator::Iterator::next", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"]
1216
- ["lang:core", "crate::iter::traits::iterator::Iterator::collect", "Argument[self].Element", "ReturnValue.Element", "value", "manual"]
17+
- ["lang:core", "crate::iter::traits::iterator::Iterator::map", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
18+
- ["lang:core", "crate::iter::traits::iterator::Iterator::for_each", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
19+
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::nth", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"]
20+
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::next", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"]
21+
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::collect", "Argument[self].Element", "ReturnValue.Element", "value", "manual"]
22+
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::map", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
23+
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::for_each", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
1324
# Option
1425
- ["lang:core", "<crate::option::Option>::expect", "Argument[self].Field[crate::option::Option::Some(0)]", "ReturnValue", "value", "manual"]
1526
# Result
@@ -24,6 +35,9 @@ extensions:
2435
- ["lang:core", "<crate::result::Result>::unwrap_err_unchecked", "Argument[self].Field[crate::result::Result::Err(0)]", "ReturnValue", "value", "manual"]
2536
- ["lang:core", "<crate::result::Result>::expect", "Argument[self].Field[crate::result::Result::Ok(0)]", "ReturnValue", "value", "manual"]
2637
- ["lang:core", "<crate::result::Result>::expect_err", "Argument[self].Field[crate::result::Result::Err(0)]", "ReturnValue", "value", "manual"]
38+
# Str
39+
- ["lang:core", "<str>::parse", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
2740
# String
2841
- ["lang:alloc", "<crate::string::String>::as_str", "Argument[self]", "ReturnValue", "taint", "manual"]
2942
- ["lang:alloc", "<crate::string::String>::as_bytes", "Argument[self]", "ReturnValue", "taint", "manual"]
43+
- ["lang:alloc", "<_ as crate::string::ToString>::to_string", "Argument[self]", "ReturnValue", "taint", "manual"]

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

+172-30
Large diffs are not rendered by default.

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

+43-20
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,23 @@ edges
187187
| main.rs:421:10:421:16 | mut_arr [element] | main.rs:421:10:421:19 | mut_arr[0] | provenance | |
188188
| main.rs:444:9:444:9 | s | main.rs:445:10:445:10 | s | provenance | |
189189
| main.rs:444:25:444:26 | source(...) | main.rs:444:9:444:9 | s | provenance | |
190-
| main.rs:449:9:449:9 | a | main.rs:454:10:454:10 | a | provenance | |
191-
| main.rs:449:13:449:22 | source(...) | main.rs:449:9:449:9 | a | provenance | |
192-
| main.rs:451:9:451:9 | c | main.rs:452:18:452:18 | c | provenance | |
193-
| main.rs:451:13:451:22 | source(...) | main.rs:451:9:451:9 | c | provenance | |
194-
| main.rs:452:9:452:13 | c_ref [&ref] | main.rs:457:11:457:15 | c_ref [&ref] | provenance | |
195-
| main.rs:452:17:452:18 | &c [&ref] | main.rs:452:9:452:13 | c_ref [&ref] | provenance | |
196-
| main.rs:452:18:452:18 | c | main.rs:452:17:452:18 | &c [&ref] | provenance | |
197-
| main.rs:457:11:457:15 | c_ref [&ref] | main.rs:457:10:457:15 | * ... | provenance | |
190+
| main.rs:453:9:453:9 | a | main.rs:458:10:458:10 | a | provenance | |
191+
| main.rs:453:13:453:22 | source(...) | main.rs:453:9:453:9 | a | provenance | |
192+
| main.rs:465:9:465:10 | vs [element] | main.rs:467:10:467:11 | vs [element] | provenance | |
193+
| main.rs:465:9:465:10 | vs [element] | main.rs:471:14:471:15 | vs [element] | provenance | |
194+
| main.rs:465:14:465:34 | [...] [element] | main.rs:465:9:465:10 | vs [element] | provenance | |
195+
| main.rs:465:15:465:24 | source(...) | main.rs:465:14:465:34 | [...] [element] | provenance | |
196+
| main.rs:467:10:467:11 | vs [element] | main.rs:467:10:467:14 | vs[0] | provenance | |
197+
| main.rs:471:9:471:9 | v | main.rs:472:14:472:14 | v | provenance | |
198+
| main.rs:471:14:471:15 | vs [element] | main.rs:471:9:471:9 | v | provenance | |
199+
| main.rs:502:9:502:9 | a | main.rs:507:10:507:10 | a | provenance | |
200+
| main.rs:502:13:502:22 | source(...) | main.rs:502:9:502:9 | a | provenance | |
201+
| main.rs:504:9:504:9 | c | main.rs:505:18:505:18 | c | provenance | |
202+
| main.rs:504:13:504:22 | source(...) | main.rs:504:9:504:9 | c | provenance | |
203+
| main.rs:505:9:505:13 | c_ref [&ref] | main.rs:510:11:510:15 | c_ref [&ref] | provenance | |
204+
| main.rs:505:17:505:18 | &c [&ref] | main.rs:505:9:505:13 | c_ref [&ref] | provenance | |
205+
| main.rs:505:18:505:18 | c | main.rs:505:17:505:18 | &c [&ref] | provenance | |
206+
| main.rs:510:11:510:15 | c_ref [&ref] | main.rs:510:10:510:15 | * ... | provenance | |
198207
nodes
199208
| main.rs:18:10:18:18 | source(...) | semmle.label | source(...) |
200209
| main.rs:22:9:22:9 | s | semmle.label | s |
@@ -411,16 +420,27 @@ nodes
411420
| main.rs:444:9:444:9 | s | semmle.label | s |
412421
| main.rs:444:25:444:26 | source(...) | semmle.label | source(...) |
413422
| main.rs:445:10:445:10 | s | semmle.label | s |
414-
| main.rs:449:9:449:9 | a | semmle.label | a |
415-
| main.rs:449:13:449:22 | source(...) | semmle.label | source(...) |
416-
| main.rs:451:9:451:9 | c | semmle.label | c |
417-
| main.rs:451:13:451:22 | source(...) | semmle.label | source(...) |
418-
| main.rs:452:9:452:13 | c_ref [&ref] | semmle.label | c_ref [&ref] |
419-
| main.rs:452:17:452:18 | &c [&ref] | semmle.label | &c [&ref] |
420-
| main.rs:452:18:452:18 | c | semmle.label | c |
421-
| main.rs:454:10:454:10 | a | semmle.label | a |
422-
| main.rs:457:10:457:15 | * ... | semmle.label | * ... |
423-
| main.rs:457:11:457:15 | c_ref [&ref] | semmle.label | c_ref [&ref] |
423+
| main.rs:453:9:453:9 | a | semmle.label | a |
424+
| main.rs:453:13:453:22 | source(...) | semmle.label | source(...) |
425+
| main.rs:458:10:458:10 | a | semmle.label | a |
426+
| main.rs:465:9:465:10 | vs [element] | semmle.label | vs [element] |
427+
| main.rs:465:14:465:34 | [...] [element] | semmle.label | [...] [element] |
428+
| main.rs:465:15:465:24 | source(...) | semmle.label | source(...) |
429+
| main.rs:467:10:467:11 | vs [element] | semmle.label | vs [element] |
430+
| main.rs:467:10:467:14 | vs[0] | semmle.label | vs[0] |
431+
| main.rs:471:9:471:9 | v | semmle.label | v |
432+
| main.rs:471:14:471:15 | vs [element] | semmle.label | vs [element] |
433+
| main.rs:472:14:472:14 | v | semmle.label | v |
434+
| main.rs:502:9:502:9 | a | semmle.label | a |
435+
| main.rs:502:13:502:22 | source(...) | semmle.label | source(...) |
436+
| main.rs:504:9:504:9 | c | semmle.label | c |
437+
| main.rs:504:13:504:22 | source(...) | semmle.label | source(...) |
438+
| main.rs:505:9:505:13 | c_ref [&ref] | semmle.label | c_ref [&ref] |
439+
| main.rs:505:17:505:18 | &c [&ref] | semmle.label | &c [&ref] |
440+
| main.rs:505:18:505:18 | c | semmle.label | c |
441+
| main.rs:507:10:507:10 | a | semmle.label | a |
442+
| main.rs:510:10:510:15 | * ... | semmle.label | * ... |
443+
| main.rs:510:11:510:15 | c_ref [&ref] | semmle.label | c_ref [&ref] |
424444
subpaths
425445
testFailures
426446
#select
@@ -466,5 +486,8 @@ testFailures
466486
| main.rs:420:10:420:10 | d | main.rs:418:18:418:27 | source(...) | main.rs:420:10:420:10 | d | $@ | main.rs:418:18:418:27 | source(...) | source(...) |
467487
| main.rs:421:10:421:19 | mut_arr[0] | main.rs:418:18:418:27 | source(...) | main.rs:421:10:421:19 | mut_arr[0] | $@ | main.rs:418:18:418:27 | source(...) | source(...) |
468488
| main.rs:445:10:445:10 | s | main.rs:444:25:444:26 | source(...) | main.rs:445:10:445:10 | s | $@ | main.rs:444:25:444:26 | source(...) | source(...) |
469-
| main.rs:454:10:454:10 | a | main.rs:449:13:449:22 | source(...) | main.rs:454:10:454:10 | a | $@ | main.rs:449:13:449:22 | source(...) | source(...) |
470-
| main.rs:457:10:457:15 | * ... | main.rs:451:13:451:22 | source(...) | main.rs:457:10:457:15 | * ... | $@ | main.rs:451:13:451:22 | source(...) | source(...) |
489+
| main.rs:458:10:458:10 | a | main.rs:453:13:453:22 | source(...) | main.rs:458:10:458:10 | a | $@ | main.rs:453:13:453:22 | source(...) | source(...) |
490+
| main.rs:467:10:467:14 | vs[0] | main.rs:465:15:465:24 | source(...) | main.rs:467:10:467:14 | vs[0] | $@ | main.rs:465:15:465:24 | source(...) | source(...) |
491+
| main.rs:472:14:472:14 | v | main.rs:465:15:465:24 | source(...) | main.rs:472:14:472:14 | v | $@ | main.rs:465:15:465:24 | source(...) | source(...) |
492+
| main.rs:507:10:507:10 | a | main.rs:502:13:502:22 | source(...) | main.rs:507:10:507:10 | a | $@ | main.rs:502:13:502:22 | source(...) | source(...) |
493+
| main.rs:510:10:510:15 | * ... | main.rs:504:13:504:22 | source(...) | main.rs:510:10:510:15 | * ... | $@ | main.rs:504:13:504:22 | source(...) | source(...) |

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

+55
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,59 @@ fn macro_invocation() {
445445
sink(s); // $ hasValueFlow=37
446446
}
447447

448+
fn sink_string(s: String) {
449+
println!("{}", s);
450+
}
451+
452+
fn parse() {
453+
let a = source(90);
454+
let b = a.to_string();
455+
let c = b.parse::<i64>().unwrap();
456+
let d : i64 = b.parse().unwrap();
457+
458+
sink(a); // $ hasValueFlow=90
459+
sink_string(b); // $ hasTaintFlow=90
460+
sink(c); // $ hasTaintFlow=90
461+
sink(d); // $ hasTaintFlow=90
462+
}
463+
464+
fn iterators() {
465+
let vs = [source(91), 2, 3, 4];
466+
467+
sink(vs[0]); // $ hasValueFlow=91
468+
sink(*vs.iter().next().unwrap()); // $ MISSING: hasValueFlow=91
469+
sink(*vs.iter().nth(0).unwrap()); // $ MISSING: hasValueFlow=91
470+
471+
for v in vs {
472+
sink(v); // $ hasValueFlow=91
473+
}
474+
for &v in vs.iter() {
475+
sink(v); // $ MISSING: hasValueFlow=91
476+
}
477+
478+
let vs2 : Vec<&i64> = vs.iter().collect();
479+
for &v in vs2 {
480+
sink(v); // $ MISSING: hasValueFlow=91
481+
}
482+
483+
vs.iter().map(|x| sink(*x)); // $ MISSING: hasValueFlow=91
484+
vs.iter().for_each(|x| sink(*x)); // $ MISSING: hasValueFlow=91
485+
486+
for v in vs.into_iter() {
487+
sink(v); // $ MISSING: hasValueFlow=91
488+
}
489+
490+
let mut vs_mut = [source(92), 2, 3, 4];
491+
492+
sink(vs_mut[0]); // $ MISSING: hasValueFlow=92
493+
sink(*vs_mut.iter().next().unwrap()); // $ MISSING: hasValueFlow=92
494+
sink(*vs_mut.iter().nth(0).unwrap()); // $ MISSING: hasValueFlow=92
495+
496+
for &mut v in vs_mut.iter_mut() {
497+
sink(v); // $ MISSING: hasValueFlow=92
498+
}
499+
}
500+
448501
fn references() {
449502
let a = source(40);
450503
let b = source(41);
@@ -494,5 +547,7 @@ fn main() {
494547
array_assignment();
495548
captured_variable_and_continue(vec![]);
496549
macro_invocation();
550+
parse();
551+
iterators();
497552
references();
498553
}

rust/ql/test/library-tests/dataflow/sources/TaintSources.expected

+16-15
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
| test.rs:29:29:29:42 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
88
| test.rs:32:16:32:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
99
| test.rs:33:16:33:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. |
10-
| test.rs:40:16:40:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
11-
| test.rs:44:16:44:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. |
12-
| test.rs:50:15:50:35 | ...::current_dir | Flow source 'CommandLineArgs' of type commandargs. |
13-
| test.rs:51:15:51:35 | ...::current_exe | Flow source 'CommandLineArgs' of type commandargs. |
14-
| test.rs:52:16:52:33 | ...::home_dir | Flow source 'CommandLineArgs' of type commandargs. |
15-
| test.rs:60:26:60:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
16-
| test.rs:63:26:63:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
17-
| test.rs:66:26:66:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
18-
| test.rs:69:26:69:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
19-
| test.rs:72:26:72:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
20-
| test.rs:75:26:75:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
21-
| test.rs:78:24:78:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
22-
| test.rs:110:35:110:46 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
23-
| test.rs:117:31:117:42 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
24-
| test.rs:201:16:201:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
10+
| test.rs:34:16:34:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
11+
| test.rs:42:16:42:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |
12+
| test.rs:46:16:46:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. |
13+
| test.rs:52:15:52:35 | ...::current_dir | Flow source 'CommandLineArgs' of type commandargs. |
14+
| test.rs:53:15:53:35 | ...::current_exe | Flow source 'CommandLineArgs' of type commandargs. |
15+
| test.rs:54:16:54:33 | ...::home_dir | Flow source 'CommandLineArgs' of type commandargs. |
16+
| test.rs:62:26:62:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
17+
| test.rs:65:26:65:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
18+
| test.rs:68:26:68:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
19+
| test.rs:71:26:71:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
20+
| test.rs:74:26:74:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
21+
| test.rs:77:26:77:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
22+
| test.rs:80:24:80:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
23+
| test.rs:112:35:112:46 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
24+
| test.rs:119:31:119:42 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
25+
| test.rs:203:16:203:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. |

rust/ql/test/library-tests/dataflow/sources/test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ fn test_env_args() {
3131
let arg1 = &args[1];
3232
let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources]
3333
let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources]
34+
let arg4 = std::env::args().nth(4).unwrap().parse::<usize>().unwrap(); // $ Alert[rust/summary/taint-sources]
3435

3536
sink(my_path); // $ hasTaintFlow
3637
sink(arg1); // $ hasTaintFlow
3738
sink(arg2); // $ hasTaintFlow
3839
sink(arg3); // $ hasTaintFlow
40+
sink(arg4); // $ hasTaintFlow
3941

4042
for arg in std::env::args() { // $ Alert[rust/summary/taint-sources]
4143
sink(arg); // $ hasTaintFlow

0 commit comments

Comments
 (0)