Rust: Split off sources/database test.

This commit is contained in:
Geoffrey White
2025-10-21 16:25:11 +01:00
parent 81132beec0
commit 7ddd441e5f
9 changed files with 2505 additions and 216 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
models
| 1 | Source: <_ as mysql::conn::queryable::Queryable>::query_first; ReturnValue.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; database |
| 2 | Source: <_ as mysql::conn::queryable::Queryable>::query_fold; Argument[2].Parameter[1]; database |
| 3 | Source: <_ as mysql::conn::queryable::Queryable>::query_map; Argument[1].Parameter[0]; database |
| 4 | Source: <_ as mysql_async::queryable::Queryable>::query_fold; Argument[2].Parameter[1]; database |
| 5 | Source: <_ as mysql_async::queryable::Queryable>::query_map; Argument[1].Parameter[0]; database |
| 6 | Source: <mysql::conn::pool::PooledConn as mysql::conn::queryable::Queryable>::exec_iter; ReturnValue.Field[core::result::Result::Ok(0)].Element; database |
| 7 | Source: <mysql_common::row::Row>::get; ReturnValue.Field[core::option::Option::Some(0)]; database |
| 8 | Source: <mysql_common::row::Row>::get_opt; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; database |
| 9 | Source: <mysql_common::row::Row>::take; ReturnValue.Field[core::option::Option::Some(0)]; database |
| 10 | Source: <mysql_common::row::Row>::take_opt; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; database |
| 11 | Summary: <_ as core::ops::arith::Add>::add; Argument[0].Reference; ReturnValue; taint |
| 12 | Summary: <_ as core::ops::arith::Add>::add; Argument[0]; ReturnValue; taint |
| 13 | Summary: <_ as mysql::conn::queryable::Queryable>::query_fold; Argument[2].ReturnValue; ReturnValue.Field[core::result::Result::Ok(0)]; value |
| 14 | Summary: <_ as mysql_async::queryable::Queryable>::query_fold; Argument[2].ReturnValue; ReturnValue.Future.Field[core::result::Result::Ok(0)]; value |
| 15 | Summary: <core::i64 as core::ops::arith::Add>::add; Argument[0]; ReturnValue; taint |
| 16 | Summary: <core::option::Option>::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value |
| 17 | Summary: <core::result::Result>::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
edges
| test.rs:18:13:18:14 | v1 | test.rs:19:14:19:15 | v1 | provenance | |
| test.rs:18:24:18:33 | row.get(...) [Some] | test.rs:18:24:18:42 | ... .unwrap() | provenance | MaD:16 |
| test.rs:18:24:18:42 | ... .unwrap() | test.rs:18:13:18:14 | v1 | provenance | |
| test.rs:18:28:18:30 | get | test.rs:18:24:18:33 | row.get(...) [Some] | provenance | Src:MaD:7 |
| test.rs:21:13:21:14 | v2 | test.rs:22:14:22:15 | v2 | provenance | |
| test.rs:21:24:21:37 | row.get_opt(...) [Some, Ok] | test.rs:21:24:21:46 | ... .unwrap() [Ok] | provenance | MaD:16 |
| test.rs:21:24:21:46 | ... .unwrap() [Ok] | test.rs:21:24:21:55 | ... .unwrap() | provenance | MaD:17 |
| test.rs:21:24:21:55 | ... .unwrap() | test.rs:21:13:21:14 | v2 | provenance | |
| test.rs:21:28:21:34 | get_opt | test.rs:21:24:21:37 | row.get_opt(...) [Some, Ok] | provenance | Src:MaD:8 |
| test.rs:24:13:24:14 | v3 | test.rs:25:14:25:15 | v3 | provenance | |
| test.rs:24:24:24:34 | row.take(...) [Some] | test.rs:24:24:24:43 | ... .unwrap() | provenance | MaD:16 |
| test.rs:24:24:24:43 | ... .unwrap() | test.rs:24:13:24:14 | v3 | provenance | |
| test.rs:24:28:24:31 | take | test.rs:24:24:24:34 | row.take(...) [Some] | provenance | Src:MaD:9 |
| test.rs:27:13:27:14 | v4 | test.rs:28:14:28:15 | v4 | provenance | |
| test.rs:27:24:27:38 | row.take_opt(...) [Some, Ok] | test.rs:27:24:27:47 | ... .unwrap() [Ok] | provenance | MaD:16 |
| test.rs:27:24:27:47 | ... .unwrap() [Ok] | test.rs:27:24:27:56 | ... .unwrap() | provenance | MaD:17 |
| test.rs:27:24:27:56 | ... .unwrap() | test.rs:27:13:27:14 | v4 | provenance | |
| test.rs:27:28:27:35 | take_opt | test.rs:27:24:27:38 | row.take_opt(...) [Some, Ok] | provenance | Src:MaD:10 |
| test.rs:37:13:37:14 | v6 | test.rs:38:14:38:15 | v6 | provenance | |
| test.rs:37:23:37:63 | conn.query_first(...) [Ok, Some] | test.rs:37:23:37:64 | TryExpr [Some] | provenance | |
| test.rs:37:23:37:64 | TryExpr [Some] | test.rs:37:23:37:73 | ... .unwrap() | provenance | MaD:16 |
| test.rs:37:23:37:73 | ... .unwrap() | test.rs:37:13:37:14 | v6 | provenance | |
| test.rs:37:28:37:38 | query_first | test.rs:37:23:37:63 | conn.query_first(...) [Ok, Some] | provenance | Src:MaD:1 |
| test.rs:40:13:40:18 | mut t1 [element] | test.rs:42:20:42:21 | t1 [element] | provenance | |
| test.rs:40:22:40:71 | conn.exec_iter(...) [Ok, element] | test.rs:40:22:40:72 | TryExpr [element] | provenance | |
| test.rs:40:22:40:72 | TryExpr [element] | test.rs:40:13:40:18 | mut t1 [element] | provenance | |
| test.rs:40:27:40:35 | exec_iter | test.rs:40:22:40:71 | conn.exec_iter(...) [Ok, element] | provenance | Src:MaD:6 |
| test.rs:41:14:41:61 | ... .get(...) [Some] | test.rs:41:14:41:70 | ... .unwrap() | provenance | MaD:16 |
| test.rs:41:42:41:44 | get | test.rs:41:14:41:61 | ... .get(...) [Some] | provenance | Src:MaD:7 |
| test.rs:42:13:42:15 | row | test.rs:44:22:44:22 | v | provenance | |
| test.rs:42:20:42:21 | t1 [element] | test.rs:42:13:42:15 | row | provenance | |
| test.rs:48:22:48:30 | query_map | test.rs:50:14:50:24 | ...: i64 | provenance | Src:MaD:3 |
| test.rs:50:14:50:24 | ...: i64 | test.rs:51:22:51:27 | values | provenance | |
| test.rs:64:13:64:17 | total | test.rs:68:14:68:18 | total | provenance | |
| test.rs:64:21:67:10 | conn.query_fold(...) [Ok] | test.rs:64:21:67:11 | TryExpr | provenance | |
| test.rs:64:21:67:11 | TryExpr | test.rs:64:13:64:17 | total | provenance | |
| test.rs:64:26:64:35 | query_fold | test.rs:64:76:64:83 | ...: i64 | provenance | Src:MaD:2 |
| test.rs:64:76:64:83 | ...: i64 | test.rs:64:86:67:9 | { ... } | provenance | |
| test.rs:64:76:64:83 | ...: i64 | test.rs:65:18:65:20 | row | provenance | |
| test.rs:64:76:64:83 | ...: i64 | test.rs:66:19:66:21 | row | provenance | |
| test.rs:64:86:67:9 | { ... } | test.rs:64:21:67:10 | conn.query_fold(...) [Ok] | provenance | MaD:13 |
| test.rs:66:13:66:21 | ... + ... | test.rs:64:86:67:9 | { ... } | provenance | |
| test.rs:66:19:66:21 | row | test.rs:66:13:66:21 | ... + ... | provenance | MaD:11 |
| test.rs:66:19:66:21 | row | test.rs:66:13:66:21 | ... + ... | provenance | MaD:12 |
| test.rs:66:19:66:21 | row | test.rs:66:13:66:21 | ... + ... | provenance | MaD:15 |
| test.rs:105:13:105:14 | v1 | test.rs:106:14:106:15 | v1 | provenance | |
| test.rs:105:24:105:33 | row.get(...) [Some] | test.rs:105:24:105:42 | ... .unwrap() | provenance | MaD:16 |
| test.rs:105:24:105:42 | ... .unwrap() | test.rs:105:13:105:14 | v1 | provenance | |
| test.rs:105:28:105:30 | get | test.rs:105:24:105:33 | row.get(...) [Some] | provenance | Src:MaD:7 |
| test.rs:108:13:108:14 | v2 | test.rs:109:14:109:15 | v2 | provenance | |
| test.rs:108:24:108:37 | row.get_opt(...) [Some, Ok] | test.rs:108:24:108:46 | ... .unwrap() [Ok] | provenance | MaD:16 |
| test.rs:108:24:108:46 | ... .unwrap() [Ok] | test.rs:108:24:108:55 | ... .unwrap() | provenance | MaD:17 |
| test.rs:108:24:108:55 | ... .unwrap() | test.rs:108:13:108:14 | v2 | provenance | |
| test.rs:108:28:108:34 | get_opt | test.rs:108:24:108:37 | row.get_opt(...) [Some, Ok] | provenance | Src:MaD:8 |
| test.rs:111:13:111:14 | v3 | test.rs:112:14:112:15 | v3 | provenance | |
| test.rs:111:24:111:34 | row.take(...) [Some] | test.rs:111:24:111:43 | ... .unwrap() | provenance | MaD:16 |
| test.rs:111:24:111:43 | ... .unwrap() | test.rs:111:13:111:14 | v3 | provenance | |
| test.rs:111:28:111:31 | take | test.rs:111:24:111:34 | row.take(...) [Some] | provenance | Src:MaD:9 |
| test.rs:114:13:114:14 | v4 | test.rs:115:14:115:15 | v4 | provenance | |
| test.rs:114:24:114:38 | row.take_opt(...) [Some, Ok] | test.rs:114:24:114:47 | ... .unwrap() [Ok] | provenance | MaD:16 |
| test.rs:114:24:114:47 | ... .unwrap() [Ok] | test.rs:114:24:114:56 | ... .unwrap() | provenance | MaD:17 |
| test.rs:114:24:114:56 | ... .unwrap() | test.rs:114:13:114:14 | v4 | provenance | |
| test.rs:114:28:114:35 | take_opt | test.rs:114:24:114:38 | row.take_opt(...) [Some, Ok] | provenance | Src:MaD:10 |
| test.rs:135:22:135:30 | query_map | test.rs:137:14:137:24 | ...: i64 | provenance | Src:MaD:5 |
| test.rs:137:14:137:24 | ...: i64 | test.rs:138:22:138:27 | values | provenance | |
| test.rs:151:13:151:17 | total | test.rs:155:14:155:18 | total | provenance | |
| test.rs:151:21:154:10 | conn.query_fold(...) [future, Ok] | test.rs:151:21:154:16 | await ... [Ok] | provenance | |
| test.rs:151:21:154:16 | await ... [Ok] | test.rs:151:21:154:17 | TryExpr | provenance | |
| test.rs:151:21:154:17 | TryExpr | test.rs:151:13:151:17 | total | provenance | |
| test.rs:151:26:151:35 | query_fold | test.rs:151:76:151:83 | ...: i64 | provenance | Src:MaD:4 |
| test.rs:151:76:151:83 | ...: i64 | test.rs:151:86:154:9 | { ... } | provenance | |
| test.rs:151:76:151:83 | ...: i64 | test.rs:152:18:152:20 | row | provenance | |
| test.rs:151:76:151:83 | ...: i64 | test.rs:153:19:153:21 | row | provenance | |
| test.rs:151:86:154:9 | { ... } | test.rs:151:21:154:10 | conn.query_fold(...) [future, Ok] | provenance | MaD:14 |
| test.rs:153:13:153:21 | ... + ... | test.rs:151:86:154:9 | { ... } | provenance | |
| test.rs:153:19:153:21 | row | test.rs:153:13:153:21 | ... + ... | provenance | MaD:11 |
| test.rs:153:19:153:21 | row | test.rs:153:13:153:21 | ... + ... | provenance | MaD:12 |
| test.rs:153:19:153:21 | row | test.rs:153:13:153:21 | ... + ... | provenance | MaD:15 |
nodes
| test.rs:18:13:18:14 | v1 | semmle.label | v1 |
| test.rs:18:24:18:33 | row.get(...) [Some] | semmle.label | row.get(...) [Some] |
| test.rs:18:24:18:42 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:18:28:18:30 | get | semmle.label | get |
| test.rs:19:14:19:15 | v1 | semmle.label | v1 |
| test.rs:21:13:21:14 | v2 | semmle.label | v2 |
| test.rs:21:24:21:37 | row.get_opt(...) [Some, Ok] | semmle.label | row.get_opt(...) [Some, Ok] |
| test.rs:21:24:21:46 | ... .unwrap() [Ok] | semmle.label | ... .unwrap() [Ok] |
| test.rs:21:24:21:55 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:21:28:21:34 | get_opt | semmle.label | get_opt |
| test.rs:22:14:22:15 | v2 | semmle.label | v2 |
| test.rs:24:13:24:14 | v3 | semmle.label | v3 |
| test.rs:24:24:24:34 | row.take(...) [Some] | semmle.label | row.take(...) [Some] |
| test.rs:24:24:24:43 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:24:28:24:31 | take | semmle.label | take |
| test.rs:25:14:25:15 | v3 | semmle.label | v3 |
| test.rs:27:13:27:14 | v4 | semmle.label | v4 |
| test.rs:27:24:27:38 | row.take_opt(...) [Some, Ok] | semmle.label | row.take_opt(...) [Some, Ok] |
| test.rs:27:24:27:47 | ... .unwrap() [Ok] | semmle.label | ... .unwrap() [Ok] |
| test.rs:27:24:27:56 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:27:28:27:35 | take_opt | semmle.label | take_opt |
| test.rs:28:14:28:15 | v4 | semmle.label | v4 |
| test.rs:37:13:37:14 | v6 | semmle.label | v6 |
| test.rs:37:23:37:63 | conn.query_first(...) [Ok, Some] | semmle.label | conn.query_first(...) [Ok, Some] |
| test.rs:37:23:37:64 | TryExpr [Some] | semmle.label | TryExpr [Some] |
| test.rs:37:23:37:73 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:37:28:37:38 | query_first | semmle.label | query_first |
| test.rs:38:14:38:15 | v6 | semmle.label | v6 |
| test.rs:40:13:40:18 | mut t1 [element] | semmle.label | mut t1 [element] |
| test.rs:40:22:40:71 | conn.exec_iter(...) [Ok, element] | semmle.label | conn.exec_iter(...) [Ok, element] |
| test.rs:40:22:40:72 | TryExpr [element] | semmle.label | TryExpr [element] |
| test.rs:40:27:40:35 | exec_iter | semmle.label | exec_iter |
| test.rs:41:14:41:61 | ... .get(...) [Some] | semmle.label | ... .get(...) [Some] |
| test.rs:41:14:41:70 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:41:42:41:44 | get | semmle.label | get |
| test.rs:42:13:42:15 | row | semmle.label | row |
| test.rs:42:20:42:21 | t1 [element] | semmle.label | t1 [element] |
| test.rs:44:22:44:22 | v | semmle.label | v |
| test.rs:48:22:48:30 | query_map | semmle.label | query_map |
| test.rs:50:14:50:24 | ...: i64 | semmle.label | ...: i64 |
| test.rs:51:22:51:27 | values | semmle.label | values |
| test.rs:64:13:64:17 | total | semmle.label | total |
| test.rs:64:21:67:10 | conn.query_fold(...) [Ok] | semmle.label | conn.query_fold(...) [Ok] |
| test.rs:64:21:67:11 | TryExpr | semmle.label | TryExpr |
| test.rs:64:26:64:35 | query_fold | semmle.label | query_fold |
| test.rs:64:76:64:83 | ...: i64 | semmle.label | ...: i64 |
| test.rs:64:86:67:9 | { ... } | semmle.label | { ... } |
| test.rs:65:18:65:20 | row | semmle.label | row |
| test.rs:66:13:66:21 | ... + ... | semmle.label | ... + ... |
| test.rs:66:19:66:21 | row | semmle.label | row |
| test.rs:68:14:68:18 | total | semmle.label | total |
| test.rs:105:13:105:14 | v1 | semmle.label | v1 |
| test.rs:105:24:105:33 | row.get(...) [Some] | semmle.label | row.get(...) [Some] |
| test.rs:105:24:105:42 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:105:28:105:30 | get | semmle.label | get |
| test.rs:106:14:106:15 | v1 | semmle.label | v1 |
| test.rs:108:13:108:14 | v2 | semmle.label | v2 |
| test.rs:108:24:108:37 | row.get_opt(...) [Some, Ok] | semmle.label | row.get_opt(...) [Some, Ok] |
| test.rs:108:24:108:46 | ... .unwrap() [Ok] | semmle.label | ... .unwrap() [Ok] |
| test.rs:108:24:108:55 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:108:28:108:34 | get_opt | semmle.label | get_opt |
| test.rs:109:14:109:15 | v2 | semmle.label | v2 |
| test.rs:111:13:111:14 | v3 | semmle.label | v3 |
| test.rs:111:24:111:34 | row.take(...) [Some] | semmle.label | row.take(...) [Some] |
| test.rs:111:24:111:43 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:111:28:111:31 | take | semmle.label | take |
| test.rs:112:14:112:15 | v3 | semmle.label | v3 |
| test.rs:114:13:114:14 | v4 | semmle.label | v4 |
| test.rs:114:24:114:38 | row.take_opt(...) [Some, Ok] | semmle.label | row.take_opt(...) [Some, Ok] |
| test.rs:114:24:114:47 | ... .unwrap() [Ok] | semmle.label | ... .unwrap() [Ok] |
| test.rs:114:24:114:56 | ... .unwrap() | semmle.label | ... .unwrap() |
| test.rs:114:28:114:35 | take_opt | semmle.label | take_opt |
| test.rs:115:14:115:15 | v4 | semmle.label | v4 |
| test.rs:135:22:135:30 | query_map | semmle.label | query_map |
| test.rs:137:14:137:24 | ...: i64 | semmle.label | ...: i64 |
| test.rs:138:22:138:27 | values | semmle.label | values |
| test.rs:151:13:151:17 | total | semmle.label | total |
| test.rs:151:21:154:10 | conn.query_fold(...) [future, Ok] | semmle.label | conn.query_fold(...) [future, Ok] |
| test.rs:151:21:154:16 | await ... [Ok] | semmle.label | await ... [Ok] |
| test.rs:151:21:154:17 | TryExpr | semmle.label | TryExpr |
| test.rs:151:26:151:35 | query_fold | semmle.label | query_fold |
| test.rs:151:76:151:83 | ...: i64 | semmle.label | ...: i64 |
| test.rs:151:86:154:9 | { ... } | semmle.label | { ... } |
| test.rs:152:18:152:20 | row | semmle.label | row |
| test.rs:153:13:153:21 | ... + ... | semmle.label | ... + ... |
| test.rs:153:19:153:21 | row | semmle.label | row |
| test.rs:155:14:155:18 | total | semmle.label | total |
subpaths
testFailures
#select
| test.rs:19:14:19:15 | v1 | test.rs:18:28:18:30 | get | test.rs:19:14:19:15 | v1 | $@ | test.rs:18:28:18:30 | get | get |
| test.rs:22:14:22:15 | v2 | test.rs:21:28:21:34 | get_opt | test.rs:22:14:22:15 | v2 | $@ | test.rs:21:28:21:34 | get_opt | get_opt |
| test.rs:25:14:25:15 | v3 | test.rs:24:28:24:31 | take | test.rs:25:14:25:15 | v3 | $@ | test.rs:24:28:24:31 | take | take |
| test.rs:28:14:28:15 | v4 | test.rs:27:28:27:35 | take_opt | test.rs:28:14:28:15 | v4 | $@ | test.rs:27:28:27:35 | take_opt | take_opt |
| test.rs:38:14:38:15 | v6 | test.rs:37:28:37:38 | query_first | test.rs:38:14:38:15 | v6 | $@ | test.rs:37:28:37:38 | query_first | query_first |
| test.rs:41:14:41:70 | ... .unwrap() | test.rs:41:42:41:44 | get | test.rs:41:14:41:70 | ... .unwrap() | $@ | test.rs:41:42:41:44 | get | get |
| test.rs:44:22:44:22 | v | test.rs:40:27:40:35 | exec_iter | test.rs:44:22:44:22 | v | $@ | test.rs:40:27:40:35 | exec_iter | exec_iter |
| test.rs:51:22:51:27 | values | test.rs:48:22:48:30 | query_map | test.rs:51:22:51:27 | values | $@ | test.rs:48:22:48:30 | query_map | query_map |
| test.rs:65:18:65:20 | row | test.rs:64:26:64:35 | query_fold | test.rs:65:18:65:20 | row | $@ | test.rs:64:26:64:35 | query_fold | query_fold |
| test.rs:68:14:68:18 | total | test.rs:64:26:64:35 | query_fold | test.rs:68:14:68:18 | total | $@ | test.rs:64:26:64:35 | query_fold | query_fold |
| test.rs:106:14:106:15 | v1 | test.rs:105:28:105:30 | get | test.rs:106:14:106:15 | v1 | $@ | test.rs:105:28:105:30 | get | get |
| test.rs:109:14:109:15 | v2 | test.rs:108:28:108:34 | get_opt | test.rs:109:14:109:15 | v2 | $@ | test.rs:108:28:108:34 | get_opt | get_opt |
| test.rs:112:14:112:15 | v3 | test.rs:111:28:111:31 | take | test.rs:112:14:112:15 | v3 | $@ | test.rs:111:28:111:31 | take | take |
| test.rs:115:14:115:15 | v4 | test.rs:114:28:114:35 | take_opt | test.rs:115:14:115:15 | v4 | $@ | test.rs:114:28:114:35 | take_opt | take_opt |
| test.rs:138:22:138:27 | values | test.rs:135:22:135:30 | query_map | test.rs:138:22:138:27 | values | $@ | test.rs:135:22:135:30 | query_map | query_map |
| test.rs:152:18:152:20 | row | test.rs:151:26:151:35 | query_fold | test.rs:152:18:152:20 | row | $@ | test.rs:151:26:151:35 | query_fold | query_fold |
| test.rs:155:14:155:18 | total | test.rs:151:26:151:35 | query_fold | test.rs:155:14:155:18 | total | $@ | test.rs:151:26:151:35 | query_fold | query_fold |

View File

@@ -0,0 +1,36 @@
/**
* @kind path-problem
*/
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.Concepts
import utils.test.InlineFlowTest
/**
* Configuration for flow from any threat model source to an argument of the function `sink`.
*/
module MyFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource }
predicate isSink(DataFlow::Node sink) {
any(CallExpr call |
call.getFunction().(PathExpr).getPath().getSegment().getIdentifier().getText() = "sink"
).getArgList().getAnArg() = sink.asExpr().getExpr()
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
// flow out from any content at the sink.
isSink(node) and
exists(c)
}
}
module MyFlowTest = TaintFlowTest<MyFlowConfig>;
import MyFlowTest
import PathGraph
from PathNode source, PathNode sink
where flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,25 @@
| test.rs:15:47:15:51 | query | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:18:28:18:30 | get | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:21:28:21:34 | get_opt | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:24:28:24:31 | take | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:27:28:27:35 | take_opt | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:30:26:30:31 | as_ref | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:37:28:37:38 | query_first | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:40:27:40:35 | exec_iter | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:41:42:41:44 | get | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:48:22:48:30 | query_map | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:55:22:55:30 | query_map | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:64:26:64:35 | query_fold | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:70:22:70:31 | query_fold | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:102:53:102:57 | query | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:105:28:105:30 | get | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:108:28:108:34 | get_opt | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:111:28:111:31 | take | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:114:28:114:35 | take_opt | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:117:26:117:31 | as_ref | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:124:28:124:38 | query_first | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:127:27:127:35 | exec_iter | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:135:22:135:30 | query_map | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:142:22:142:30 | query_map | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:151:26:151:35 | query_fold | Flow source 'DatabaseSource' of type database (DEFAULT). |
| test.rs:157:22:157:31 | query_fold | Flow source 'DatabaseSource' of type database (DEFAULT). |

View File

@@ -0,0 +1,2 @@
query: queries/summary/TaintSources.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,7 @@
qltest_cargo_check: true
qltest_dependencies:
- async-std = { version = "1.13.1" }
- futures = { version = "0.3" }
- mysql = { version = "26.0.1" }
- mysql_async = { version = "0.36.1" }
- tokio = { version = "1.43.0", features = ["full"] }

View File

@@ -0,0 +1,222 @@
fn sink<T>(_: T) { }
// --- tests ---
mod test_mysql {
use mysql::*;
use mysql::prelude::*;
use super::sink;
pub fn test_mysql() -> Result<(), Box<dyn std::error::Error>> {
// connect through a MySQL connection pool
let mut pool = mysql::Pool::new("")?;
let mut conn = pool.get_conn()?;
let mut rows : Vec<mysql::Row> = conn.query("SELECT id, name, age FROM person")?; // $ Alert[rust/summary/taint-sources]
let mut row = &mut rows[0];
let v1 : i64 = row.get(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v1); // $ hasTaintFlow=0
let v2 : i64 = row.get_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v2); // $ hasTaintFlow=0
let v3 : i64 = row.take(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v3); // $ hasTaintFlow=0
let v4 : i64 = row.take_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v4); // $ hasTaintFlow=0
let value5 = row.as_ref(0).unwrap(); // $ Alert[rust/summary/taint-sources]
if let mysql::Value::Int(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
} else if let mysql::Value::Bytes(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
}
let v6: i64 = conn.query_first("SELECT id FROM person")?.unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v6); // $ hasTaintFlow
let mut t1 = conn.exec_iter("SELECT id FROM person", (1, 2, 3))?; // $ Alert[rust/summary/taint-sources]
sink(t1.nth(0).unwrap().unwrap().get::<i64, usize>(1).unwrap()); // $ Alert[rust/summary/taint-sources] hasTaintFlow=1
for row in t1 {
for v in row {
sink(v); // $ hasTaintFlow
}
}
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id FROM person",
|values: i64| -> () {
sink(values); // $ hasTaintFlow
}
)?;
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id, name, age FROM person",
|values: (i64, String, i32)| -> () {
sink(values.0); // $ MISSING: hasTaintFlow
sink(values.1); // $ MISSING: hasTaintFlow
sink(values.2); // $ MISSING: hasTaintFlow
}
)?;
let total = conn.query_fold("SELECT id FROM person", 0, |acc: i64, row: i64| { // $ Alert[rust/summary/taint-sources]
sink(row); // $ hasTaintFlow
acc + row
})?;
sink(total); // $ hasTaintFlow
let _ = conn.query_fold("SELECT id, name, age FROM person", 0, |acc: i64, row: (i64, String, i32)| { // $ Alert[rust/summary/taint-sources]
let id: i64 = row.0;
let name: String = row.1;
let age: i32 = row.2;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
acc + 1
})?;
Ok(())
}
}
mod test_mysql_async {
use mysql_async::*;
use mysql_async::prelude::*;
use async_std::stream::StreamExt;
use super::sink;
#[derive(Debug, PartialEq, Eq, Clone)]
struct Person {
id: i64,
name: String,
age: i32,
}
pub async fn test_mysql_async() -> Result<()> {
// connect through a MySQL connection pool
let mut pool = mysql_async::Pool::new("");
let mut conn = pool.get_conn().await?;
let mut rows : Vec<mysql_async::Row> = conn.query("SELECT id, name, age FROM person").await?; // $ Alert[rust/summary/taint-sources]
let mut row = &mut rows[0];
let v1 : i64 = row.get(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v1); // $ hasTaintFlow=0
let v2 : i64 = row.get_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v2); // $ hasTaintFlow=0
let v3 : i64 = row.take(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v3); // $ hasTaintFlow=0
let v4 : i64 = row.take_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v4); // $ hasTaintFlow=0
let value5 = row.as_ref(0).unwrap(); // $ Alert[rust/summary/taint-sources]
if let mysql_async::Value::Int(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
} else if let mysql_async::Value::Bytes(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
}
let v6: i64 = conn.query_first("SELECT id FROM person").await?.unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v6); // $ MISSING: hasTaintFlow
let mut t1 = conn.exec_iter("SELECT id FROM person", (1, 2, 3)).await?; // $ Alert[rust/summary/taint-sources]
for mut row in t1.stream::<(i64, String, i32)>().await? {
while let v = row.next().await {
let v = v.unwrap();
sink(v); // $ MISSING: hasTaintFlow
}
}
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id FROM person",
|values: i64| -> () {
sink(values); // $ hasTaintFlow
}
).await?;
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id, name, age FROM person",
|values: (i64, String, i32)| -> () {
sink(values.0); // $ MISSING: hasTaintFlow
sink(values.1); // $ MISSING: hasTaintFlow
sink(values.2); // $ MISSING: hasTaintFlow
}
).await?;
let total = conn.query_fold("SELECT id FROM person", 0, |acc: i64, row: i64| { // $ Alert[rust/summary/taint-sources]
sink(row); // $ hasTaintFlow
acc + row
}).await?;
sink(total); // $ hasTaintFlow
let _ = conn.query_fold("SELECT id, name, age FROM person", 0, |acc: i64, row: (i64, String, i32)| { // $ Alert[rust/summary/taint-sources]
let id: i64 = row.0;
let name: String = row.1;
let age: i32 = row.2;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
acc + 1
}).await?;
let ids = "SELECT id FROM person".with(()).map(&mut conn,
|person: i64| -> i64 {
sink(person); // $ MISSING: hasTaintFlow
person
}
).await?;
sink(ids[0]); // $ MISSING: hasTaintFlow
let ages = "SELECT id, name, age FROM person".with(()).map(&mut conn, // $ MISSING: Alert[rust/summary/taint-sources]
|person: (i64, String, i32)| -> i32 {
sink(person.0); // $ MISSING: hasTaintFlow
sink(person.1); // $ MISSING: hasTaintFlow
sink(person.2); // $ MISSING: hasTaintFlow
person.2
}
).await?;
sink(ages[0]); // $ MISSING: hasTaintFlow
{
let mut stream = "SELECT id FROM person".stream::<i64, _>(&mut conn).await?; // $ MISSING: Alert[rust/summary/taint-sources]
while let Some(row) = stream.next().await {
let id = row?;
sink(id); // $ MISSING: hasTaintFlow
}
}
{
let mut stream = "SELECT id, name, age FROM person".stream::<(i64, String, i32), _>(&mut conn).await?; // $ MISSING: Alert[rust/summary/taint-sources]
while let Some(row) = stream.next().await {
let (id, name, age) = row?;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
}
}
Ok(())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("test_mysql...");
match test_mysql::test_mysql() {
Ok(_) => println!("complete"),
Err(e) => println!("error: {}", e),
}
println!("test_mysql_async...");
match futures::executor::block_on(test_mysql_async::test_mysql_async()) {
Ok(_) => println!("complete"),
Err(e) => println!("error: {}", e),
}
Ok(())
}

View File

@@ -16,5 +16,3 @@ qltest_dependencies:
- futures-rustls = { version = "0.26.0" }
- async-std = { version = "1.13.1" }
- warp = { version = "0.4.2", features = ["server"] }
- mysql = { version = "26.0.1" }
- mysql_async = { version = "0.36.1" }

View File

@@ -358,208 +358,6 @@ fn test_rustls() -> std::io::Result<()> {
Ok(())
}
mod test_mysql {
use mysql::*;
use mysql::prelude::*;
use super::sink;
pub fn test_mysql() -> Result<(), Box<dyn std::error::Error>> {
// connect through a MySQL connection pool
let mut pool = mysql::Pool::new("")?;
let mut conn = pool.get_conn()?;
let mut rows : Vec<mysql::Row> = conn.query("SELECT id, name, age FROM person")?; // $ Alert[rust/summary/taint-sources]
let mut row = &mut rows[0];
let v1 : i64 = row.get(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v1); // $ hasTaintFlow=0
let v2 : i64 = row.get_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v2); // $ hasTaintFlow=0
let v3 : i64 = row.take(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v3); // $ hasTaintFlow=0
let v4 : i64 = row.take_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v4); // $ hasTaintFlow=0
let value5 = row.as_ref(0).unwrap(); // $ Alert[rust/summary/taint-sources]
if let mysql::Value::Int(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
} else if let mysql::Value::Bytes(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
}
let v6: i64 = conn.query_first("SELECT id FROM person")?.unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v6); // $ hasTaintFlow
let mut t1 = conn.exec_iter("SELECT id FROM person", (1, 2, 3))?; // $ Alert[rust/summary/taint-sources]
sink(t1.nth(0).unwrap().unwrap().get::<i64, usize>(1).unwrap()); // $ Alert[rust/summary/taint-sources] hasTaintFlow=1
for row in t1 {
for v in row {
sink(v); // $ hasTaintFlow
}
}
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id FROM person",
|values: i64| -> () {
sink(values); // $ hasTaintFlow
}
)?;
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id, name, age FROM person",
|values: (i64, String, i32)| -> () {
sink(values.0); // $ MISSING: hasTaintFlow
sink(values.1); // $ MISSING: hasTaintFlow
sink(values.2); // $ MISSING: hasTaintFlow
}
)?;
let total = conn.query_fold("SELECT id FROM person", 0, |acc: i64, row: i64| { // $ Alert[rust/summary/taint-sources]
sink(row); // $ hasTaintFlow
acc + row
})?;
sink(total); // $ hasTaintFlow
let _ = conn.query_fold("SELECT id, name, age FROM person", 0, |acc: i64, row: (i64, String, i32)| { // $ Alert[rust/summary/taint-sources]
let id: i64 = row.0;
let name: String = row.1;
let age: i32 = row.2;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
acc + 1
})?;
Ok(())
}
}
mod test_mysql_async {
use mysql_async::*;
use mysql_async::prelude::*;
use async_std::stream::StreamExt;
use super::sink;
#[derive(Debug, PartialEq, Eq, Clone)]
struct Person {
id: i64,
name: String,
age: i32,
}
pub async fn test_mysql_async() -> Result<()> {
// connect through a MySQL connection pool
let mut pool = mysql_async::Pool::new("");
let mut conn = pool.get_conn().await?;
let mut rows : Vec<mysql_async::Row> = conn.query("SELECT id, name, age FROM person").await?; // $ Alert[rust/summary/taint-sources]
let mut row = &mut rows[0];
let v1 : i64 = row.get(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v1); // $ hasTaintFlow=0
let v2 : i64 = row.get_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v2); // $ hasTaintFlow=0
let v3 : i64 = row.take(0).unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v3); // $ hasTaintFlow=0
let v4 : i64 = row.take_opt(0).unwrap().unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v4); // $ hasTaintFlow=0
let value5 = row.as_ref(0).unwrap(); // $ Alert[rust/summary/taint-sources]
if let mysql_async::Value::Int(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
} else if let mysql_async::Value::Bytes(v) = value5 {
sink(v); // $ MISSING: hasTaintFlow=0
}
let v6: i64 = conn.query_first("SELECT id FROM person").await?.unwrap(); // $ Alert[rust/summary/taint-sources]
sink(v6); // $ MISSING: hasTaintFlow
let mut t1 = conn.exec_iter("SELECT id FROM person", (1, 2, 3)).await?; // $ Alert[rust/summary/taint-sources]
for mut row in t1.stream::<(i64, String, i32)>().await? {
while let v = row.next().await {
let v = v.unwrap();
sink(v); // $ MISSING: hasTaintFlow
}
}
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id FROM person",
|values: i64| -> () {
sink(values); // $ hasTaintFlow
}
).await?;
let _ = conn.query_map( // $ Alert[rust/summary/taint-sources]
"SELECT id, name, age FROM person",
|values: (i64, String, i32)| -> () {
sink(values.0); // $ MISSING: hasTaintFlow
sink(values.1); // $ MISSING: hasTaintFlow
sink(values.2); // $ MISSING: hasTaintFlow
}
).await?;
let total = conn.query_fold("SELECT id FROM person", 0, |acc: i64, row: i64| { // $ Alert[rust/summary/taint-sources]
sink(row); // $ hasTaintFlow
acc + row
}).await?;
sink(total); // $ hasTaintFlow
let _ = conn.query_fold("SELECT id, name, age FROM person", 0, |acc: i64, row: (i64, String, i32)| { // $ Alert[rust/summary/taint-sources]
let id: i64 = row.0;
let name: String = row.1;
let age: i32 = row.2;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
acc + 1
}).await?;
let ids = "SELECT id FROM person".with(()).map(&mut conn,
|person: i64| -> i64 {
sink(person); // $ MISSING: hasTaintFlow
person
}
).await?;
sink(ids[0]); // $ MISSING: hasTaintFlow
let ages = "SELECT id, name, age FROM person".with(()).map(&mut conn, // $ MISSING: Alert[rust/summary/taint-sources]
|person: (i64, String, i32)| -> i32 {
sink(person.0); // $ MISSING: hasTaintFlow
sink(person.1); // $ MISSING: hasTaintFlow
sink(person.2); // $ MISSING: hasTaintFlow
person.2
}
).await?;
sink(ages[0]); // $ MISSING: hasTaintFlow
{
let mut stream = "SELECT id FROM person".stream::<i64, _>(&mut conn).await?; // $ MISSING: Alert[rust/summary/taint-sources]
while let Some(row) = stream.next().await {
let id = row?;
sink(id); // $ MISSING: hasTaintFlow
}
}
{
let mut stream = "SELECT id, name, age FROM person".stream::<(i64, String, i32), _>(&mut conn).await?; // $ MISSING: Alert[rust/summary/taint-sources]
while let Some(row) = stream.next().await {
let (id, name, age) = row?;
sink(id); // $ MISSING: hasTaintFlow
sink(name); // $ MISSING: hasTaintFlow
sink(age); // $ MISSING: hasTaintFlow
}
}
Ok(())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let case = std::env::args().nth(1).unwrap_or(String::from("1")).parse::<i64>().unwrap(); // $ Alert[rust/summary/taint-sources]
@@ -600,17 +398,5 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Err(e) => println!("error: {}", e),
}
println!("test_mysql...");
match test_mysql::test_mysql() {
Ok(_) => println!("complete"),
Err(e) => println!("error: {}", e),
}
println!("test_mysql_async...");
match futures::executor::block_on(test_mysql_async::test_mysql_async()) {
Ok(_) => println!("complete"),
Err(e) => println!("error: {}", e),
}
Ok(())
}