diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected index 9a1f25d2b830..f8e1a1e4c7cb 100644 --- a/rust/ql/integration-tests/hello-project/summary.expected +++ b/rust/ql/integration-tests/hello-project/summary.expected @@ -14,7 +14,7 @@ | Macro calls - resolved | 2 | | Macro calls - total | 2 | | Macro calls - unresolved | 0 | -| Taint edges - number of edges | 4 | +| Taint edges - number of edges | 10 | | Taint reach - nodes tainted | 0 | | Taint reach - per million nodes | 0 | | Taint sinks - cryptographic operations | 0 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected index 9ab7d2a15d91..efea91e69a1d 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected @@ -14,7 +14,7 @@ | Macro calls - resolved | 2 | | Macro calls - total | 2 | | Macro calls - unresolved | 0 | -| Taint edges - number of edges | 4 | +| Taint edges - number of edges | 10 | | Taint reach - nodes tainted | 0 | | Taint reach - per million nodes | 0 | | Taint sinks - cryptographic operations | 0 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected index 9ab7d2a15d91..efea91e69a1d 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected @@ -14,7 +14,7 @@ | Macro calls - resolved | 2 | | Macro calls - total | 2 | | Macro calls - unresolved | 0 | -| Taint edges - number of edges | 4 | +| Taint edges - number of edges | 10 | | Taint reach - nodes tainted | 0 | | Taint reach - per million nodes | 0 | | Taint sinks - cryptographic operations | 0 | diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml index ceaa836fed8d..04c4fceb87a2 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml @@ -8,8 +8,19 @@ extensions: # Hint - ["lang:core", "crate::hint::must_use", "Argument[0]", "ReturnValue", "value", "manual"] # Iterator + - ["lang:core", "<[_]>::iter", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"] + - ["lang:core", "<[_]>::iter_mut", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"] + - ["lang:core", "<[_]>::into_iter", "Argument[Self].Element", "ReturnValue.Element", "value", "manual"] - ["lang:core", "crate::iter::traits::iterator::Iterator::nth", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"] + - ["lang:core", "crate::iter::traits::iterator::Iterator::next", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"] - ["lang:core", "crate::iter::traits::iterator::Iterator::collect", "Argument[self].Element", "ReturnValue.Element", "value", "manual"] + - ["lang:core", "crate::iter::traits::iterator::Iterator::map", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["lang:core", "crate::iter::traits::iterator::Iterator::for_each", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["lang:core", "::nth", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"] + - ["lang:core", "::next", "Argument[self].Element", "ReturnValue.Field[crate::option::Option::Some(0)]", "value", "manual"] + - ["lang:core", "::collect", "Argument[self].Element", "ReturnValue.Element", "value", "manual"] + - ["lang:core", "::map", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["lang:core", "::for_each", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"] # Option - ["lang:core", "::expect", "Argument[self].Field[crate::option::Option::Some(0)]", "ReturnValue", "value", "manual"] # Result @@ -24,6 +35,9 @@ extensions: - ["lang:core", "::unwrap_err_unchecked", "Argument[self].Field[crate::result::Result::Err(0)]", "ReturnValue", "value", "manual"] - ["lang:core", "::expect", "Argument[self].Field[crate::result::Result::Ok(0)]", "ReturnValue", "value", "manual"] - ["lang:core", "::expect_err", "Argument[self].Field[crate::result::Result::Err(0)]", "ReturnValue", "value", "manual"] + # Str + - ["lang:core", "::parse", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"] # String - ["lang:alloc", "::as_str", "Argument[self]", "ReturnValue", "taint", "manual"] - ["lang:alloc", "::as_bytes", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["lang:alloc", "<_ as crate::string::ToString>::to_string", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index e3c8608162a3..432aade94030 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -4,6 +4,10 @@ localStep | file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::::is_some_and | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::is_some_and | MaD:26 | | file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::::map | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::map | MaD:28 | | file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::::take_if | file://:0:0:0:0 | [summary] to write: Argument[self].Reference.Field[crate::option::Option::Some(0)] in lang:core::_::::take_if | MaD:43 | +| file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::::for_each | file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::::for_each | MaD:74 | +| file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::::map | file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::::map | MaD:75 | +| file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | MaD:80 | +| file://:0:0:0:0 | [post] [summary] to write: Argument[0].Parameter[0] in lang:core::_::crate::iter::traits::iterator::Iterator::map | file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::map | MaD:81 | | file://:0:0:0:0 | [post] [summary] to write: Argument[1].Parameter[0] in lang:core::_::::map_or | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::map_or | MaD:31 | | file://:0:0:0:0 | [post] [summary] to write: Argument[1].Parameter[0] in lang:core::_::::map_or_else | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::map_or_else | MaD:34 | | file://:0:0:0:0 | [post] [summary] to write: Argument[1].Parameter[0] in lang:core::_::::zip_with | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | MaD:61 | @@ -34,7 +38,11 @@ localStep | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::xor | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::xor | MaD:55 | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unwrap_or | MaD:67 | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::unwrap_or_else | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[closure self] in lang:core::_::::unwrap_or_else | MaD:70 | -| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::hint::must_use | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::hint::must_use | MaD:73 | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::for_each | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[closure self] in lang:core::_::::for_each | MaD:74 | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::::map | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[closure self] in lang:core::_::::map | MaD:75 | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::hint::must_use | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::hint::must_use | MaD:78 | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[closure self] in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | MaD:80 | +| file://:0:0:0:0 | [summary param] 0 in lang:core::_::crate::iter::traits::iterator::Iterator::map | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[closure self] in lang:core::_::crate::iter::traits::iterator::Iterator::map | MaD:81 | | file://:0:0:0:0 | [summary param] 1 in lang:core::_::::map_or | file://:0:0:0:0 | [summary] to write: Argument[1].Parameter[closure self] in lang:core::_::::map_or | MaD:30 | | file://:0:0:0:0 | [summary param] 1 in lang:core::_::::map_or | file://:0:0:0:0 | [summary] to write: Argument[1].Parameter[closure self] in lang:core::_::::map_or | MaD:31 | | file://:0:0:0:0 | [summary param] 1 in lang:core::_::::map_or_else | file://:0:0:0:0 | [summary] to write: Argument[1].Parameter[closure self] in lang:core::_::::map_or_else | MaD:33 | @@ -61,8 +69,16 @@ localStep | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:core::_::::map_or | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::map_or | MaD:30 | | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:core::_::::map_or_else | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::map_or_else | MaD:33 | | file://:0:0:0:0 | [summary] read: Argument[1].ReturnValue in lang:core::_::::zip_with | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | MaD:60 | -| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | file://:0:0:0:0 | [summary] to write: ReturnValue.Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | MaD:74 | -| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::nth | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::crate::iter::traits::iterator::Iterator::nth | MaD:75 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::collect | file://:0:0:0:0 | [summary] to write: ReturnValue.Element in lang:core::_::::collect | MaD:73 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::for_each | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[0] in lang:core::_::::for_each | MaD:74 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::map | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[0] in lang:core::_::::map | MaD:75 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::next | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::next | MaD:76 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::nth | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::nth | MaD:77 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | file://:0:0:0:0 | [summary] to write: ReturnValue.Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | MaD:79 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[0] in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | MaD:80 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::map | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[0] in lang:core::_::crate::iter::traits::iterator::Iterator::map | MaD:81 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::next | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::crate::iter::traits::iterator::Iterator::next | MaD:82 | +| file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::nth | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::crate::iter::traits::iterator::Iterator::nth | MaD:83 | | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::clone | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::clone | MaD:2 | | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::and_then | file://:0:0:0:0 | [summary] to write: Argument[0].Parameter[0] in lang:core::_::::and_then | MaD:7 | | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::cloned | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::cloned | MaD:10 | @@ -721,26 +737,103 @@ localStep | main.rs:444:9:444:9 | s | main.rs:444:9:444:9 | s | | | main.rs:444:13:444:27 | MacroExpr | main.rs:444:9:444:9 | s | | | main.rs:444:25:444:26 | source(...) | main.rs:444:13:444:27 | MacroExpr | | -| main.rs:449:9:449:9 | [SSA] a | main.rs:454:10:454:10 | a | | -| main.rs:449:9:449:9 | a | main.rs:449:9:449:9 | [SSA] a | | -| main.rs:449:9:449:9 | a | main.rs:449:9:449:9 | a | | -| main.rs:449:13:449:22 | source(...) | main.rs:449:9:449:9 | a | | -| main.rs:450:9:450:9 | [SSA] b | main.rs:455:15:455:15 | b | | -| main.rs:450:9:450:9 | b | main.rs:450:9:450:9 | [SSA] b | | -| main.rs:450:9:450:9 | b | main.rs:450:9:450:9 | b | | -| main.rs:450:13:450:22 | source(...) | main.rs:450:9:450:9 | b | | -| main.rs:451:9:451:9 | [SSA] c | main.rs:452:18:452:18 | c | | -| main.rs:451:9:451:9 | c | main.rs:451:9:451:9 | [SSA] c | | -| main.rs:451:9:451:9 | c | main.rs:451:9:451:9 | c | | -| main.rs:451:13:451:22 | source(...) | main.rs:451:9:451:9 | c | | -| main.rs:452:9:452:13 | [SSA] c_ref | main.rs:456:14:456:18 | c_ref | | -| main.rs:452:9:452:13 | c_ref | main.rs:452:9:452:13 | [SSA] c_ref | | -| main.rs:452:9:452:13 | c_ref | main.rs:452:9:452:13 | c_ref | | -| main.rs:452:17:452:18 | &c | main.rs:452:9:452:13 | c_ref | | -| main.rs:456:14:456:18 | [post] c_ref | main.rs:457:11:457:15 | c_ref | | -| main.rs:456:14:456:18 | c_ref | main.rs:457:11:457:15 | c_ref | | -| main.rs:483:13:483:33 | result_questionmark(...) | main.rs:483:9:483:9 | _ | | -| main.rs:495:36:495:41 | ...::new(...) | main.rs:495:36:495:41 | MacroExpr | | +| main.rs:448:16:448:16 | [SSA] s | main.rs:449:20:449:20 | s | | +| main.rs:448:16:448:16 | s | main.rs:448:16:448:16 | [SSA] s | | +| main.rs:448:16:448:16 | s | main.rs:448:16:448:16 | s | | +| main.rs:448:16:448:24 | ...: String | main.rs:448:16:448:16 | s | | +| main.rs:449:14:449:20 | FormatArgsExpr | main.rs:449:14:449:20 | MacroExpr | | +| main.rs:449:14:449:20 | MacroExpr | main.rs:449:5:449:21 | ...::_print | MaD:1 | +| main.rs:453:9:453:9 | [SSA] a | main.rs:454:13:454:13 | a | | +| main.rs:453:9:453:9 | a | main.rs:453:9:453:9 | [SSA] a | | +| main.rs:453:9:453:9 | a | main.rs:453:9:453:9 | a | | +| main.rs:453:13:453:22 | source(...) | main.rs:453:9:453:9 | a | | +| main.rs:454:9:454:9 | [SSA] b | main.rs:455:13:455:13 | b | | +| main.rs:454:9:454:9 | b | main.rs:454:9:454:9 | [SSA] b | | +| main.rs:454:9:454:9 | b | main.rs:454:9:454:9 | b | | +| main.rs:454:13:454:13 | [post] a | main.rs:458:10:458:10 | a | | +| main.rs:454:13:454:13 | a | main.rs:458:10:458:10 | a | | +| main.rs:454:13:454:25 | a.to_string(...) | main.rs:454:9:454:9 | b | | +| main.rs:455:9:455:9 | [SSA] c | main.rs:460:10:460:10 | c | | +| main.rs:455:9:455:9 | c | main.rs:455:9:455:9 | [SSA] c | | +| main.rs:455:9:455:9 | c | main.rs:455:9:455:9 | c | | +| main.rs:455:13:455:13 | [post] b | main.rs:456:19:456:19 | b | | +| main.rs:455:13:455:13 | b | main.rs:456:19:456:19 | b | | +| main.rs:455:13:455:37 | ... .unwrap(...) | main.rs:455:9:455:9 | c | | +| main.rs:456:9:456:9 | [SSA] d | main.rs:461:10:461:10 | d | | +| main.rs:456:9:456:9 | d | main.rs:456:9:456:9 | [SSA] d | | +| main.rs:456:9:456:9 | d | main.rs:456:9:456:9 | d | | +| main.rs:456:19:456:19 | [post] b | main.rs:459:17:459:17 | b | | +| main.rs:456:19:456:19 | b | main.rs:459:17:459:17 | b | | +| main.rs:456:19:456:36 | ... .unwrap(...) | main.rs:456:9:456:9 | d | | +| main.rs:465:9:465:10 | [SSA] vs | main.rs:467:10:467:11 | vs | | +| main.rs:465:9:465:10 | vs | main.rs:465:9:465:10 | [SSA] vs | | +| main.rs:465:9:465:10 | vs | main.rs:465:9:465:10 | vs | | +| main.rs:465:14:465:34 | [...] | main.rs:465:9:465:10 | vs | | +| main.rs:467:10:467:11 | [post] vs | main.rs:468:11:468:12 | vs | | +| main.rs:467:10:467:11 | vs | main.rs:468:11:468:12 | vs | | +| main.rs:468:11:468:12 | [post] vs | main.rs:469:11:469:12 | vs | | +| main.rs:468:11:468:12 | vs | main.rs:469:11:469:12 | vs | | +| main.rs:469:11:469:12 | [post] vs | main.rs:471:14:471:15 | vs | | +| main.rs:469:11:469:12 | vs | main.rs:471:14:471:15 | vs | | +| main.rs:471:9:471:9 | [SSA] v | main.rs:472:14:472:14 | v | | +| main.rs:471:9:471:9 | v | main.rs:471:9:471:9 | [SSA] v | | +| main.rs:471:9:471:9 | v | main.rs:471:9:471:9 | v | | +| main.rs:471:14:471:15 | vs | main.rs:474:15:474:16 | vs | | +| main.rs:474:10:474:10 | [SSA] v | main.rs:475:14:475:14 | v | | +| main.rs:474:10:474:10 | v | main.rs:474:10:474:10 | [SSA] v | | +| main.rs:474:10:474:10 | v | main.rs:474:10:474:10 | v | | +| main.rs:474:15:474:16 | [post] vs | main.rs:478:27:478:28 | vs | | +| main.rs:474:15:474:16 | vs | main.rs:478:27:478:28 | vs | | +| main.rs:478:9:478:11 | [SSA] vs2 | main.rs:479:15:479:17 | vs2 | | +| main.rs:478:9:478:11 | vs2 | main.rs:478:9:478:11 | [SSA] vs2 | | +| main.rs:478:9:478:11 | vs2 | main.rs:478:9:478:11 | vs2 | | +| main.rs:478:27:478:28 | [post] vs | main.rs:483:5:483:6 | vs | | +| main.rs:478:27:478:28 | vs | main.rs:483:5:483:6 | vs | | +| main.rs:478:27:478:45 | ... .collect(...) | main.rs:478:9:478:11 | vs2 | | +| main.rs:479:10:479:10 | [SSA] v | main.rs:480:14:480:14 | v | | +| main.rs:479:10:479:10 | v | main.rs:479:10:479:10 | [SSA] v | | +| main.rs:479:10:479:10 | v | main.rs:479:10:479:10 | v | | +| main.rs:483:5:483:6 | [post] vs | main.rs:484:5:484:6 | vs | | +| main.rs:483:5:483:6 | vs | main.rs:484:5:484:6 | vs | | +| main.rs:483:20:483:20 | ... | main.rs:483:20:483:20 | x | | +| main.rs:483:20:483:20 | [SSA] x | main.rs:483:29:483:29 | x | | +| main.rs:483:20:483:20 | x | main.rs:483:20:483:20 | [SSA] x | | +| main.rs:483:20:483:20 | x | main.rs:483:20:483:20 | x | | +| main.rs:484:5:484:6 | [post] vs | main.rs:486:14:486:15 | vs | | +| main.rs:484:5:484:6 | vs | main.rs:486:14:486:15 | vs | | +| main.rs:484:25:484:25 | ... | main.rs:484:25:484:25 | x | | +| main.rs:484:25:484:25 | [SSA] x | main.rs:484:34:484:34 | x | | +| main.rs:484:25:484:25 | x | main.rs:484:25:484:25 | [SSA] x | | +| main.rs:484:25:484:25 | x | main.rs:484:25:484:25 | x | | +| main.rs:486:9:486:9 | [SSA] v | main.rs:487:14:487:14 | v | | +| main.rs:486:9:486:9 | v | main.rs:486:9:486:9 | [SSA] v | | +| main.rs:486:9:486:9 | v | main.rs:486:9:486:9 | v | | +| main.rs:490:9:490:18 | mut vs_mut | main.rs:490:13:490:18 | vs_mut | | +| main.rs:490:22:490:42 | [...] | main.rs:490:9:490:18 | mut vs_mut | | +| main.rs:496:5:498:5 | for ... in ... { ... } | main.rs:464:16:499:1 | { ... } | | +| main.rs:496:14:496:14 | [SSA] v | main.rs:497:14:497:14 | v | | +| main.rs:496:14:496:14 | v | main.rs:496:14:496:14 | [SSA] v | | +| main.rs:496:14:496:14 | v | main.rs:496:14:496:14 | v | | +| main.rs:502:9:502:9 | [SSA] a | main.rs:507:10:507:10 | a | | +| main.rs:502:9:502:9 | a | main.rs:502:9:502:9 | [SSA] a | | +| main.rs:502:9:502:9 | a | main.rs:502:9:502:9 | a | | +| main.rs:502:13:502:22 | source(...) | main.rs:502:9:502:9 | a | | +| main.rs:503:9:503:9 | [SSA] b | main.rs:508:15:508:15 | b | | +| main.rs:503:9:503:9 | b | main.rs:503:9:503:9 | [SSA] b | | +| main.rs:503:9:503:9 | b | main.rs:503:9:503:9 | b | | +| main.rs:503:13:503:22 | source(...) | main.rs:503:9:503:9 | b | | +| main.rs:504:9:504:9 | [SSA] c | main.rs:505:18:505:18 | c | | +| main.rs:504:9:504:9 | c | main.rs:504:9:504:9 | [SSA] c | | +| main.rs:504:9:504:9 | c | main.rs:504:9:504:9 | c | | +| main.rs:504:13:504:22 | source(...) | main.rs:504:9:504:9 | c | | +| main.rs:505:9:505:13 | [SSA] c_ref | main.rs:509:14:509:18 | c_ref | | +| main.rs:505:9:505:13 | c_ref | main.rs:505:9:505:13 | [SSA] c_ref | | +| main.rs:505:9:505:13 | c_ref | main.rs:505:9:505:13 | c_ref | | +| main.rs:505:17:505:18 | &c | main.rs:505:9:505:13 | c_ref | | +| main.rs:509:14:509:18 | [post] c_ref | main.rs:510:11:510:15 | c_ref | | +| main.rs:509:14:509:18 | c_ref | main.rs:510:11:510:15 | c_ref | | +| main.rs:536:13:536:33 | result_questionmark(...) | main.rs:536:9:536:9 | _ | | +| main.rs:548:36:548:41 | ...::new(...) | main.rs:548:36:548:41 | MacroExpr | | models | 1 | Sink: lang:std; crate::io::stdio::_print; log-injection; Argument[0] | | 2 | Summary: lang:core; ::clone; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue.Field[crate::option::Option::Some(0)]; value | @@ -814,11 +907,23 @@ models | 70 | Summary: lang:core; ::unwrap_or_else; Argument[0].ReturnValue; ReturnValue; value | | 71 | Summary: lang:core; ::unwrap_or_else; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | | 72 | Summary: lang:core; ::unwrap_unchecked; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 73 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | -| 74 | Summary: lang:core; crate::iter::traits::iterator::Iterator::collect; Argument[self].Element; ReturnValue.Element; value | -| 75 | Summary: lang:core; crate::iter::traits::iterator::Iterator::nth; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 73 | Summary: lang:core; ::collect; Argument[self].Element; ReturnValue.Element; value | +| 74 | Summary: lang:core; ::for_each; Argument[self].Element; Argument[0].Parameter[0]; value | +| 75 | Summary: lang:core; ::map; Argument[self].Element; Argument[0].Parameter[0]; value | +| 76 | Summary: lang:core; ::next; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 77 | Summary: lang:core; ::nth; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 78 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | +| 79 | Summary: lang:core; crate::iter::traits::iterator::Iterator::collect; Argument[self].Element; ReturnValue.Element; value | +| 80 | Summary: lang:core; crate::iter::traits::iterator::Iterator::for_each; Argument[self].Element; Argument[0].Parameter[0]; value | +| 81 | Summary: lang:core; crate::iter::traits::iterator::Iterator::map; Argument[self].Element; Argument[0].Parameter[0]; value | +| 82 | Summary: lang:core; crate::iter::traits::iterator::Iterator::next; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value | +| 83 | Summary: lang:core; crate::iter::traits::iterator::Iterator::nth; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value | storeStep | file://:0:0:0:0 | [summary] to write: Argument[0].Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | Some | file://:0:0:0:0 | [post] [summary param] 0 in lang:core::_::::zip_with | +| file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::::for_each | element | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::::for_each | +| file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::::map | element | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::::map | +| file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | element | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | +| file://:0:0:0:0 | [summary] to write: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::map | element | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::map | | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::and_then | Some | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::::and_then | | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::is_none_or | Some | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::::is_none_or | | file://:0:0:0:0 | [summary] to write: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::is_some_and | Some | file://:0:0:0:0 | [post] [summary param] self in lang:core::_::::is_some_and | @@ -832,6 +937,7 @@ storeStep | file://:0:0:0:0 | [summary] to write: Argument[self].Reference.Field[crate::option::Option::Some(0)] in lang:core::_::::get_or_insert | Some | file://:0:0:0:0 | [summary] to write: Argument[self].Reference in lang:core::_::::get_or_insert | | file://:0:0:0:0 | [summary] to write: Argument[self].Reference.Field[crate::option::Option::Some(0)] in lang:core::_::::insert | Some | file://:0:0:0:0 | [summary] to write: Argument[self].Reference in lang:core::_::::insert | | file://:0:0:0:0 | [summary] to write: Argument[self].Reference.Field[crate::option::Option::Some(0)] in lang:core::_::::take_if | Some | file://:0:0:0:0 | [summary] to write: Argument[self].Reference in lang:core::_::::take_if | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Element in lang:core::_::::collect | element | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::collect | | file://:0:0:0:0 | [summary] to write: ReturnValue.Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | element | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::iter::traits::iterator::Iterator::collect | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[0] in lang:core::_::::unzip | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::unzip | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[0].Field[crate::option::Option::Some(0)] in lang:core::_::::unzip | Some | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[0] in lang:core::_::::unzip | @@ -846,6 +952,9 @@ storeStep | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::map | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::map | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::zip | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::zip | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::zip_with | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::zip_with | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::next | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::next | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::nth | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::nth | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::crate::iter::traits::iterator::Iterator::next | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::iter::traits::iterator::Iterator::next | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::crate::iter::traits::iterator::Iterator::nth | Some | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::crate::iter::traits::iterator::Iterator::nth | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)].Field[0] in lang:core::_::::zip | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::zip | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)].Field[1] in lang:core::_::::zip | tuple.1 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::option::Option::Some(0)] in lang:core::_::::zip | @@ -855,6 +964,7 @@ storeStep | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::::ok_or | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::ok_or | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::::ok_or_else | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::ok_or_else | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::::transpose | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::transpose | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::::parse | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::::parse | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | @@ -939,9 +1049,17 @@ storeStep | main.rs:415:30:415:30 | 3 | element | main.rs:415:23:415:31 | [...] | | main.rs:418:18:418:27 | source(...) | element | main.rs:418:5:418:11 | [post] mut_arr | | main.rs:430:41:430:67 | default_name | captured default_name | main.rs:430:41:430:67 | \|...\| ... | -| main.rs:452:18:452:18 | c | &ref | main.rs:452:17:452:18 | &c | -| main.rs:455:15:455:15 | b | &ref | main.rs:455:14:455:15 | &b | -| main.rs:464:27:464:27 | 0 | Some | main.rs:464:22:464:28 | Some(...) | +| main.rs:465:15:465:24 | source(...) | element | main.rs:465:14:465:34 | [...] | +| main.rs:465:27:465:27 | 2 | element | main.rs:465:14:465:34 | [...] | +| main.rs:465:30:465:30 | 3 | element | main.rs:465:14:465:34 | [...] | +| main.rs:465:33:465:33 | 4 | element | main.rs:465:14:465:34 | [...] | +| main.rs:490:23:490:32 | source(...) | element | main.rs:490:22:490:42 | [...] | +| main.rs:490:35:490:35 | 2 | element | main.rs:490:22:490:42 | [...] | +| main.rs:490:38:490:38 | 3 | element | main.rs:490:22:490:42 | [...] | +| main.rs:490:41:490:41 | 4 | element | main.rs:490:22:490:42 | [...] | +| main.rs:505:18:505:18 | c | &ref | main.rs:505:17:505:18 | &c | +| main.rs:508:15:508:15 | b | &ref | main.rs:508:14:508:15 | &b | +| main.rs:517:27:517:27 | 0 | Some | main.rs:517:22:517:28 | Some(...) | readStep | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::from | &ref | file://:0:0:0:0 | [summary] read: Argument[0].Reference in lang:core::_::::from | | file://:0:0:0:0 | [summary param] 0 in lang:core::_::::and_then | function return | file://:0:0:0:0 | [summary] read: Argument[0].ReturnValue in lang:core::_::::and_then | @@ -996,7 +1114,15 @@ readStep | file://:0:0:0:0 | [summary param] self in lang:core::_::::unwrap_or_default | Ok | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::result::Result::Ok(0)] in lang:core::_::::unwrap_or_default | | file://:0:0:0:0 | [summary param] self in lang:core::_::::unwrap_or_else | Ok | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::result::Result::Ok(0)] in lang:core::_::::unwrap_or_else | | file://:0:0:0:0 | [summary param] self in lang:core::_::::unwrap_unchecked | Ok | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::result::Result::Ok(0)] in lang:core::_::::unwrap_unchecked | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::collect | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::collect | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::for_each | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::for_each | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::map | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::map | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::next | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::next | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::nth | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::nth | | file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::collect | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::map | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::map | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::next | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::next | | file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::nth | element | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::nth | | file://:0:0:0:0 | [summary] read: Argument[0].Reference in lang:core::_::::from | Some | file://:0:0:0:0 | [summary] read: Argument[0].Reference.Field[crate::option::Option::Some(0)] in lang:core::_::::from | | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::option::Option::Some(0)] in lang:core::_::::copied | &ref | file://:0:0:0:0 | [summary] read: Argument[self].Field[crate::option::Option::Some(0)].Reference in lang:core::_::::copied | @@ -1094,4 +1220,20 @@ readStep | main.rs:428:25:428:29 | names | element | main.rs:428:9:428:20 | TuplePat | | main.rs:430:41:430:67 | [post] \|...\| ... | captured default_name | main.rs:430:41:430:67 | [post] default_name | | main.rs:430:44:430:55 | this | captured default_name | main.rs:430:44:430:55 | default_name | -| main.rs:457:11:457:15 | c_ref | &ref | main.rs:457:10:457:15 | * ... | +| main.rs:467:10:467:11 | vs | element | main.rs:467:10:467:14 | vs[0] | +| main.rs:468:11:468:35 | ... .unwrap(...) | &ref | main.rs:468:10:468:35 | * ... | +| main.rs:469:11:469:35 | ... .unwrap(...) | &ref | main.rs:469:10:469:35 | * ... | +| main.rs:471:14:471:15 | vs | element | main.rs:471:9:471:9 | v | +| main.rs:474:9:474:10 | &... | &ref | main.rs:474:10:474:10 | v | +| main.rs:474:15:474:23 | vs.iter(...) | element | main.rs:474:9:474:10 | &... | +| main.rs:479:9:479:10 | &... | &ref | main.rs:479:10:479:10 | v | +| main.rs:479:15:479:17 | vs2 | element | main.rs:479:9:479:10 | &... | +| main.rs:483:29:483:29 | x | &ref | main.rs:483:28:483:29 | * ... | +| main.rs:484:34:484:34 | x | &ref | main.rs:484:33:484:34 | * ... | +| main.rs:486:14:486:27 | vs.into_iter(...) | element | main.rs:486:9:486:9 | v | +| main.rs:492:10:492:15 | vs_mut | element | main.rs:492:10:492:18 | vs_mut[0] | +| main.rs:493:11:493:39 | ... .unwrap(...) | &ref | main.rs:493:10:493:39 | * ... | +| main.rs:494:11:494:39 | ... .unwrap(...) | &ref | main.rs:494:10:494:39 | * ... | +| main.rs:496:9:496:14 | &mut ... | &ref | main.rs:496:14:496:14 | v | +| main.rs:496:19:496:35 | vs_mut.iter_mut(...) | element | main.rs:496:9:496:14 | &mut ... | +| main.rs:510:11:510:15 | c_ref | &ref | main.rs:510:10:510:15 | * ... | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 2995fd415d93..0c9dad76710b 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -187,14 +187,23 @@ edges | main.rs:421:10:421:16 | mut_arr [element] | main.rs:421:10:421:19 | mut_arr[0] | provenance | | | main.rs:444:9:444:9 | s | main.rs:445:10:445:10 | s | provenance | | | main.rs:444:25:444:26 | source(...) | main.rs:444:9:444:9 | s | provenance | | -| main.rs:449:9:449:9 | a | main.rs:454:10:454:10 | a | provenance | | -| main.rs:449:13:449:22 | source(...) | main.rs:449:9:449:9 | a | provenance | | -| main.rs:451:9:451:9 | c | main.rs:452:18:452:18 | c | provenance | | -| main.rs:451:13:451:22 | source(...) | main.rs:451:9:451:9 | c | provenance | | -| main.rs:452:9:452:13 | c_ref [&ref] | main.rs:457:11:457:15 | c_ref [&ref] | provenance | | -| main.rs:452:17:452:18 | &c [&ref] | main.rs:452:9:452:13 | c_ref [&ref] | provenance | | -| main.rs:452:18:452:18 | c | main.rs:452:17:452:18 | &c [&ref] | provenance | | -| main.rs:457:11:457:15 | c_ref [&ref] | main.rs:457:10:457:15 | * ... | provenance | | +| main.rs:453:9:453:9 | a | main.rs:458:10:458:10 | a | provenance | | +| main.rs:453:13:453:22 | source(...) | main.rs:453:9:453:9 | a | provenance | | +| main.rs:465:9:465:10 | vs [element] | main.rs:467:10:467:11 | vs [element] | provenance | | +| main.rs:465:9:465:10 | vs [element] | main.rs:471:14:471:15 | vs [element] | provenance | | +| main.rs:465:14:465:34 | [...] [element] | main.rs:465:9:465:10 | vs [element] | provenance | | +| main.rs:465:15:465:24 | source(...) | main.rs:465:14:465:34 | [...] [element] | provenance | | +| main.rs:467:10:467:11 | vs [element] | main.rs:467:10:467:14 | vs[0] | provenance | | +| main.rs:471:9:471:9 | v | main.rs:472:14:472:14 | v | provenance | | +| main.rs:471:14:471:15 | vs [element] | main.rs:471:9:471:9 | v | provenance | | +| main.rs:502:9:502:9 | a | main.rs:507:10:507:10 | a | provenance | | +| main.rs:502:13:502:22 | source(...) | main.rs:502:9:502:9 | a | provenance | | +| main.rs:504:9:504:9 | c | main.rs:505:18:505:18 | c | provenance | | +| main.rs:504:13:504:22 | source(...) | main.rs:504:9:504:9 | c | provenance | | +| main.rs:505:9:505:13 | c_ref [&ref] | main.rs:510:11:510:15 | c_ref [&ref] | provenance | | +| main.rs:505:17:505:18 | &c [&ref] | main.rs:505:9:505:13 | c_ref [&ref] | provenance | | +| main.rs:505:18:505:18 | c | main.rs:505:17:505:18 | &c [&ref] | provenance | | +| main.rs:510:11:510:15 | c_ref [&ref] | main.rs:510:10:510:15 | * ... | provenance | | nodes | main.rs:18:10:18:18 | source(...) | semmle.label | source(...) | | main.rs:22:9:22:9 | s | semmle.label | s | @@ -411,16 +420,27 @@ nodes | main.rs:444:9:444:9 | s | semmle.label | s | | main.rs:444:25:444:26 | source(...) | semmle.label | source(...) | | main.rs:445:10:445:10 | s | semmle.label | s | -| main.rs:449:9:449:9 | a | semmle.label | a | -| main.rs:449:13:449:22 | source(...) | semmle.label | source(...) | -| main.rs:451:9:451:9 | c | semmle.label | c | -| main.rs:451:13:451:22 | source(...) | semmle.label | source(...) | -| main.rs:452:9:452:13 | c_ref [&ref] | semmle.label | c_ref [&ref] | -| main.rs:452:17:452:18 | &c [&ref] | semmle.label | &c [&ref] | -| main.rs:452:18:452:18 | c | semmle.label | c | -| main.rs:454:10:454:10 | a | semmle.label | a | -| main.rs:457:10:457:15 | * ... | semmle.label | * ... | -| main.rs:457:11:457:15 | c_ref [&ref] | semmle.label | c_ref [&ref] | +| main.rs:453:9:453:9 | a | semmle.label | a | +| main.rs:453:13:453:22 | source(...) | semmle.label | source(...) | +| main.rs:458:10:458:10 | a | semmle.label | a | +| main.rs:465:9:465:10 | vs [element] | semmle.label | vs [element] | +| main.rs:465:14:465:34 | [...] [element] | semmle.label | [...] [element] | +| main.rs:465:15:465:24 | source(...) | semmle.label | source(...) | +| main.rs:467:10:467:11 | vs [element] | semmle.label | vs [element] | +| main.rs:467:10:467:14 | vs[0] | semmle.label | vs[0] | +| main.rs:471:9:471:9 | v | semmle.label | v | +| main.rs:471:14:471:15 | vs [element] | semmle.label | vs [element] | +| main.rs:472:14:472:14 | v | semmle.label | v | +| main.rs:502:9:502:9 | a | semmle.label | a | +| main.rs:502:13:502:22 | source(...) | semmle.label | source(...) | +| main.rs:504:9:504:9 | c | semmle.label | c | +| main.rs:504:13:504:22 | source(...) | semmle.label | source(...) | +| main.rs:505:9:505:13 | c_ref [&ref] | semmle.label | c_ref [&ref] | +| main.rs:505:17:505:18 | &c [&ref] | semmle.label | &c [&ref] | +| main.rs:505:18:505:18 | c | semmle.label | c | +| main.rs:507:10:507:10 | a | semmle.label | a | +| main.rs:510:10:510:15 | * ... | semmle.label | * ... | +| main.rs:510:11:510:15 | c_ref [&ref] | semmle.label | c_ref [&ref] | subpaths testFailures #select @@ -466,5 +486,8 @@ testFailures | 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(...) | | 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(...) | | 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(...) | -| 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(...) | -| 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(...) | +| 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(...) | +| 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(...) | +| 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(...) | +| 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(...) | +| 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(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 8d60daf128d6..33872fa8e720 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -445,6 +445,59 @@ fn macro_invocation() { sink(s); // $ hasValueFlow=37 } +fn sink_string(s: String) { + println!("{}", s); +} + +fn parse() { + let a = source(90); + let b = a.to_string(); + let c = b.parse::().unwrap(); + let d : i64 = b.parse().unwrap(); + + sink(a); // $ hasValueFlow=90 + sink_string(b); // $ hasTaintFlow=90 + sink(c); // $ hasTaintFlow=90 + sink(d); // $ hasTaintFlow=90 +} + +fn iterators() { + let vs = [source(91), 2, 3, 4]; + + sink(vs[0]); // $ hasValueFlow=91 + sink(*vs.iter().next().unwrap()); // $ MISSING: hasValueFlow=91 + sink(*vs.iter().nth(0).unwrap()); // $ MISSING: hasValueFlow=91 + + for v in vs { + sink(v); // $ hasValueFlow=91 + } + for &v in vs.iter() { + sink(v); // $ MISSING: hasValueFlow=91 + } + + let vs2 : Vec<&i64> = vs.iter().collect(); + for &v in vs2 { + sink(v); // $ MISSING: hasValueFlow=91 + } + + vs.iter().map(|x| sink(*x)); // $ MISSING: hasValueFlow=91 + vs.iter().for_each(|x| sink(*x)); // $ MISSING: hasValueFlow=91 + + for v in vs.into_iter() { + sink(v); // $ MISSING: hasValueFlow=91 + } + + let mut vs_mut = [source(92), 2, 3, 4]; + + sink(vs_mut[0]); // $ MISSING: hasValueFlow=92 + sink(*vs_mut.iter().next().unwrap()); // $ MISSING: hasValueFlow=92 + sink(*vs_mut.iter().nth(0).unwrap()); // $ MISSING: hasValueFlow=92 + + for &mut v in vs_mut.iter_mut() { + sink(v); // $ MISSING: hasValueFlow=92 + } +} + fn references() { let a = source(40); let b = source(41); @@ -494,5 +547,7 @@ fn main() { array_assignment(); captured_variable_and_continue(vec![]); macro_invocation(); + parse(); + iterators(); references(); } diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index 133942f74d9d..603ba0d76058 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -7,18 +7,19 @@ | test.rs:29:29:29:42 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | | test.rs:32:16:32:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | | test.rs:33:16:33:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:40:16:40:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:44:16:44:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:50:15:50:35 | ...::current_dir | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:51:15:51:35 | ...::current_exe | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:52:16:52:33 | ...::home_dir | Flow source 'CommandLineArgs' of type commandargs. | -| test.rs:60:26:60:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:63:26:63:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:66:26:66:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:69:26:69:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:72:26:72:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:75:26:75:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:78:24:78:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:110:35:110:46 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:117:31:117:42 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:201:16:201:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:34:16:34:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:42:16:42:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:46:16:46:32 | ...::args_os | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:52:15:52:35 | ...::current_dir | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:53:15:53:35 | ...::current_exe | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:54:16:54:33 | ...::home_dir | Flow source 'CommandLineArgs' of type commandargs. | +| test.rs:62:26:62:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:65:26:65:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:68:26:68:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:71:26:71:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:74:26:74:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:77:26:77:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:80:24:80:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:112:35:112:46 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:119:31:119:42 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:203:16:203:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs. | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 547f5443d1ba..53a5edfd8ad4 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -31,11 +31,13 @@ fn test_env_args() { let arg1 = &args[1]; let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources] let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources] + let arg4 = std::env::args().nth(4).unwrap().parse::().unwrap(); // $ Alert[rust/summary/taint-sources] sink(my_path); // $ hasTaintFlow sink(arg1); // $ hasTaintFlow sink(arg2); // $ hasTaintFlow sink(arg3); // $ hasTaintFlow + sink(arg4); // $ hasTaintFlow for arg in std::env::args() { // $ Alert[rust/summary/taint-sources] sink(arg); // $ hasTaintFlow diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected index 2c220760d479..0b92620437c2 100644 --- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected @@ -1,16 +1,26 @@ additionalTaintStep -| file://:0:0:0:0 | [summary param] 0 in lang:alloc::_::crate::fmt::format | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::crate::fmt::format | MaD:3 | -| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_bytes | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_bytes | MaD:1 | -| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_str | MaD:2 | +| file://:0:0:0:0 | [summary param] 0 in lang:alloc::_::crate::fmt::format | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::crate::fmt::format | MaD:4 | +| file://:0:0:0:0 | [summary param] self in lang:alloc::_::<_ as crate::string::ToString>::to_string | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<_ as crate::string::ToString>::to_string | MaD:1 | +| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_bytes | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_bytes | MaD:2 | +| file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_str | MaD:3 | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::collect | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::collect | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::for_each | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::for_each | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::map | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::map | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::next | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::next | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::nth | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::::nth | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::::parse | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::::parse | MaD:5 | | file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::collect | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::collect | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::for_each | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::map | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::map | | +| file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::next | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::next | | | file://:0:0:0:0 | [summary param] self in lang:core::_::crate::iter::traits::iterator::Iterator::nth | file://:0:0:0:0 | [summary] read: Argument[self].Element in lang:core::_::crate::iter::traits::iterator::Iterator::nth | | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:4 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:5 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:6 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:7 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[crate::option::Option::Some(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | MaD:8 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:9 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:10 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:6 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:7 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:8 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:9 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[crate::option::Option::Some(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | MaD:10 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:11 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:12 | | main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | | | main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | | | main.rs:8:20:8:20 | s | main.rs:8:14:8:20 | FormatArgsExpr | | @@ -28,13 +38,15 @@ additionalTaintStep | main.rs:64:24:64:27 | s[1] | main.rs:64:18:64:27 | FormatArgsExpr | | | main.rs:69:9:69:12 | arr2 | main.rs:69:9:69:15 | arr2[1] | | models -| 1 | Summary: lang:alloc; ::as_bytes; Argument[self]; ReturnValue; taint | -| 2 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint | -| 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint | -| 4 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | -| 5 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | -| 6 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | -| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | -| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::chunk; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)].Field[crate::option::Option::Some(0)]; taint | -| 9 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | -| 10 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 1 | Summary: lang:alloc; <_ as crate::string::ToString>::to_string; Argument[self]; ReturnValue; taint | +| 2 | Summary: lang:alloc; ::as_bytes; Argument[self]; ReturnValue; taint | +| 3 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint | +| 4 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint | +| 5 | Summary: lang:core; ::parse; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 6 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 9 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 10 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::chunk; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)].Field[crate::option::Option::Some(0)]; taint | +| 11 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 12 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index c3f922c52f72..97672c441163 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -14,7 +14,7 @@ | Macro calls - resolved | 8 | | Macro calls - total | 9 | | Macro calls - unresolved | 1 | -| Taint edges - number of edges | 4 | +| Taint edges - number of edges | 10 | | Taint reach - nodes tainted | 0 | | Taint reach - per million nodes | 0 | | Taint sinks - cryptographic operations | 0 | diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index c40726099858..2462328c24cc 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -1,21 +1,37 @@ #select +| sqlx.rs:62:26:62:46 | safe_query_3.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:62:26:62:46 | safe_query_3.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:73:25:73:45 | safe_query_3.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:73:25:73:45 | safe_query_3.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | edges +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:49:25:49:37 | remote_string | provenance | | | sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:56:34:56:89 | MacroExpr | provenance | | | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 | | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap(...) | provenance | MaD:4 | -| sqlx.rs:48:25:48:78 | ... .unwrap(...) | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | provenance | MaD:7 | +| sqlx.rs:48:25:48:78 | ... .unwrap(...) | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | provenance | MaD:8 | | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:5 | | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | sqlx.rs:48:9:48:21 | remote_string | provenance | | +| sqlx.rs:49:9:49:21 | remote_number | sqlx.rs:52:32:52:87 | MacroExpr | provenance | | +| sqlx.rs:49:25:49:37 | remote_string | sqlx.rs:49:25:49:52 | remote_string.parse(...) [Ok] | provenance | MaD:6 | +| sqlx.rs:49:25:49:52 | remote_string.parse(...) [Ok] | sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | provenance | MaD:5 | +| sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | sqlx.rs:49:9:49:21 | remote_number | provenance | | +| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:62:26:62:37 | safe_query_3 | provenance | | +| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:73:25:73:36 | safe_query_3 | provenance | | +| sqlx.rs:52:24:52:88 | res | sqlx.rs:52:32:52:87 | { ... } | provenance | | +| sqlx.rs:52:32:52:87 | ...::format(...) | sqlx.rs:52:24:52:88 | res | provenance | | +| sqlx.rs:52:32:52:87 | ...::must_use(...) | sqlx.rs:52:9:52:20 | safe_query_3 | provenance | | +| sqlx.rs:52:32:52:87 | MacroExpr | sqlx.rs:52:32:52:87 | ...::format(...) | provenance | MaD:3 | +| sqlx.rs:52:32:52:87 | { ... } | sqlx.rs:52:32:52:87 | ...::must_use(...) | provenance | MaD:7 | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:67:30:67:43 | unsafe_query_4 | provenance | | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:78:29:78:42 | unsafe_query_4 | provenance | | | sqlx.rs:56:26:56:90 | res | sqlx.rs:56:34:56:89 | { ... } | provenance | | | sqlx.rs:56:34:56:89 | ...::format(...) | sqlx.rs:56:26:56:90 | res | provenance | | | sqlx.rs:56:34:56:89 | ...::must_use(...) | sqlx.rs:56:9:56:22 | unsafe_query_4 | provenance | | | sqlx.rs:56:34:56:89 | MacroExpr | sqlx.rs:56:34:56:89 | ...::format(...) | provenance | MaD:3 | -| sqlx.rs:56:34:56:89 | { ... } | sqlx.rs:56:34:56:89 | ...::must_use(...) | provenance | MaD:6 | +| sqlx.rs:56:34:56:89 | { ... } | sqlx.rs:56:34:56:89 | ...::must_use(...) | provenance | MaD:7 | +| sqlx.rs:62:26:62:37 | safe_query_3 | sqlx.rs:62:26:62:46 | safe_query_3.as_str(...) | provenance | MaD:2 | | sqlx.rs:67:30:67:43 | unsafe_query_4 | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | provenance | MaD:2 | +| sqlx.rs:73:25:73:36 | safe_query_3 | sqlx.rs:73:25:73:45 | safe_query_3.as_str(...) | provenance | MaD:2 | | sqlx.rs:78:29:78:42 | unsafe_query_4 | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | provenance | MaD:2 | models | 1 | Source: repo:https://github.com/seanmonstar/reqwest:reqwest; crate::blocking::get; remote; ReturnValue.Field[crate::result::Result::Ok(0)] | @@ -23,8 +39,9 @@ models | 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint | | 4 | Summary: lang:core; ::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | | 5 | Summary: lang:core; ::unwrap_or; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value | -| 6 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | -| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 6 | Summary: lang:core; ::parse; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | +| 7 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | +| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint | nodes | sqlx.rs:48:9:48:21 | remote_string | semmle.label | remote_string | | sqlx.rs:48:25:48:46 | ...::get | semmle.label | ...::get | @@ -32,14 +49,28 @@ nodes | sqlx.rs:48:25:48:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] | | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:49:9:49:21 | remote_number | semmle.label | remote_number | +| sqlx.rs:49:25:49:37 | remote_string | semmle.label | remote_string | +| sqlx.rs:49:25:49:52 | remote_string.parse(...) [Ok] | semmle.label | remote_string.parse(...) [Ok] | +| sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:52:9:52:20 | safe_query_3 | semmle.label | safe_query_3 | +| sqlx.rs:52:24:52:88 | res | semmle.label | res | +| sqlx.rs:52:32:52:87 | ...::format(...) | semmle.label | ...::format(...) | +| sqlx.rs:52:32:52:87 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| sqlx.rs:52:32:52:87 | MacroExpr | semmle.label | MacroExpr | +| sqlx.rs:52:32:52:87 | { ... } | semmle.label | { ... } | | sqlx.rs:56:9:56:22 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:56:26:56:90 | res | semmle.label | res | | sqlx.rs:56:34:56:89 | ...::format(...) | semmle.label | ...::format(...) | | sqlx.rs:56:34:56:89 | ...::must_use(...) | semmle.label | ...::must_use(...) | | sqlx.rs:56:34:56:89 | MacroExpr | semmle.label | MacroExpr | | sqlx.rs:56:34:56:89 | { ... } | semmle.label | { ... } | +| sqlx.rs:62:26:62:37 | safe_query_3 | semmle.label | safe_query_3 | +| sqlx.rs:62:26:62:46 | safe_query_3.as_str(...) | semmle.label | safe_query_3.as_str(...) | | sqlx.rs:67:30:67:43 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | +| sqlx.rs:73:25:73:36 | safe_query_3 | semmle.label | safe_query_3 | +| sqlx.rs:73:25:73:45 | safe_query_3.as_str(...) | semmle.label | safe_query_3.as_str(...) | | sqlx.rs:78:29:78:42 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index 24d3e585e95b..f819ea3a781e 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -59,7 +59,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err // direct execution let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink let _ = conn.execute(safe_query_2.as_str()).await?; // $ sql-sink - let _ = conn.execute(safe_query_3.as_str()).await?; // $ sql-sink + let _ = conn.execute(safe_query_3.as_str()).await?; // $ sql-sink SPURIOUS: Alert[rust/sql-injection]=remote1 let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=args1 if enable_remote { let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 @@ -70,7 +70,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err // prepared queries let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ sql-sink let _ = sqlx::query(safe_query_2.as_str()).execute(&pool).await?; // $ sql-sink - let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ sql-sink + let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ sql-sink SPURIOUS: Alert[rust/sql-injection]=remote1 let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection][rust/sql-injection]=args1 if enable_remote { let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1