From d0e764d9d167de8f287af4678463925e2263b9a0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 28 Oct 2026 15:12:22 +0100 Subject: [PATCH 1/3] Rust: Add FP test for CWE-022 --- .../query-tests/security/CWE-022/Cargo.lock | 149 ++++++++++++++++-- .../security/CWE-022/TaintedPath.expected | 129 +++++++++------ .../query-tests/security/CWE-022/options.yml | 1 + .../query-tests/security/CWE-022/src/main.rs | 26 +++ 4 files changed, 240 insertions(+), 65 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-022/Cargo.lock b/rust/ql/test/query-tests/security/CWE-022/Cargo.lock index f6b8cfc2c4b4..a84a125fd6b2 100644 --- a/rust/ql/test/query-tests/security/CWE-022/Cargo.lock +++ b/rust/ql/test/query-tests/security/CWE-022/Cargo.lock @@ -151,6 +151,58 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.75" @@ -281,7 +333,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -374,7 +426,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -566,6 +618,7 @@ dependencies = [ "hyper", "pin-project-lite", "tokio", + "tower-service", ] [[package]] @@ -634,6 +687,12 @@ dependencies = [ "value-bag", ] +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.7.5" @@ -793,7 +852,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -900,7 +959,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -923,22 +982,32 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.9", ] [[package]] @@ -953,6 +1022,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1018,6 +1098,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -1032,6 +1123,7 @@ name = "test" version = "0.0.1" dependencies = [ "async-std", + "axum", "poem", "tokio", ] @@ -1053,7 +1145,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1082,7 +1174,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1115,12 +1207,41 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1134,7 +1255,7 @@ checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1207,7 +1328,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.103", "wasm-bindgen-shared", ] @@ -1242,7 +1363,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected index 6151a3eabd10..f0a2a08450c4 100644 --- a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected +++ b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected @@ -12,41 +12,43 @@ | src/main.rs:119:33:119:37 | path6 | src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:119:33:119:37 | path6 | This path depends on a $@. | src/main.rs:103:17:103:32 | ...::args(...) | user-provided value | | src/main.rs:122:27:122:39 | path1.clone() | src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:122:27:122:39 | path1.clone() | This path depends on a $@. | src/main.rs:103:17:103:32 | ...::args(...) | user-provided value | | src/main.rs:123:37:123:49 | path1.clone() | src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:123:37:123:49 | path1.clone() | This path depends on a $@. | src/main.rs:103:17:103:32 | ...::args(...) | user-provided value | -| src/main.rs:173:8:173:11 | path | src/main.rs:185:17:185:32 | ...::args(...) | src/main.rs:173:8:173:11 | path | This path depends on a $@. | src/main.rs:185:17:185:32 | ...::args(...) | user-provided value | -| src/main.rs:174:36:174:43 | path_str | src/main.rs:185:17:185:32 | ...::args(...) | src/main.rs:174:36:174:43 | path_str | This path depends on a $@. | src/main.rs:185:17:185:32 | ...::args(...) | user-provided value | -| src/main.rs:177:36:177:39 | path | src/main.rs:185:17:185:32 | ...::args(...) | src/main.rs:177:36:177:39 | path | This path depends on a $@. | src/main.rs:185:17:185:32 | ...::args(...) | user-provided value | +| src/main.rs:173:8:173:11 | path | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:173:8:173:11 | path | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | +| src/main.rs:174:36:174:43 | path_str | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:174:36:174:43 | path_str | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | +| src/main.rs:177:36:177:39 | path | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:177:36:177:39 | path | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | +| src/main.rs:192:73:192:84 | &... | src/main.rs:206:37:206:48 | destructured | src/main.rs:192:73:192:84 | &... | This path depends on a $@. | src/main.rs:206:37:206:48 | destructured | user-provided value | +| src/main.rs:201:73:201:76 | path | src/main.rs:208:33:208:39 | request | src/main.rs:201:73:201:76 | path | This path depends on a $@. | src/main.rs:208:33:208:39 | request | user-provided value | edges | src/main.rs:7:11:7:19 | file_name | src/main.rs:9:35:9:43 | file_name | provenance | | | src/main.rs:9:9:9:17 | file_path | src/main.rs:11:24:11:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:9:21:9:44 | ...::from(...) | src/main.rs:9:9:9:17 | file_path | provenance | | -| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:14 | +| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:17 | | src/main.rs:38:11:38:19 | file_path | src/main.rs:41:52:41:60 | file_path | provenance | | | src/main.rs:41:9:41:17 | file_path | src/main.rs:46:24:46:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:41:21:41:62 | public_path.join(...) | src/main.rs:41:9:41:17 | file_path | provenance | | -| src/main.rs:41:38:41:61 | ...::from(...) | src/main.rs:41:21:41:62 | public_path.join(...) | provenance | MaD:12 | -| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:14 | +| src/main.rs:41:38:41:61 | ...::from(...) | src/main.rs:41:21:41:62 | public_path.join(...) | provenance | MaD:15 | +| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:17 | | src/main.rs:63:11:63:19 | file_path | src/main.rs:66:32:66:40 | file_path | provenance | | | src/main.rs:66:9:66:17 | file_path [&ref] | src/main.rs:71:24:71:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | src/main.rs:66:9:66:17 | file_path [&ref] | provenance | | -| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:13 | +| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:16 | | src/main.rs:66:32:66:40 | file_path | src/main.rs:66:31:66:40 | &file_path [&ref] | provenance | | | src/main.rs:76:11:76:19 | file_path | src/main.rs:79:52:79:60 | file_path | provenance | | | src/main.rs:79:9:79:17 | file_path | src/main.rs:80:21:80:29 | file_path | provenance | | | src/main.rs:79:21:79:62 | public_path.join(...) | src/main.rs:79:9:79:17 | file_path | provenance | | -| src/main.rs:79:38:79:61 | ...::from(...) | src/main.rs:79:21:79:62 | public_path.join(...) | provenance | MaD:12 | -| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:14 | +| src/main.rs:79:38:79:61 | ...::from(...) | src/main.rs:79:21:79:62 | public_path.join(...) | provenance | MaD:15 | +| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:17 | | src/main.rs:80:9:80:17 | file_path | src/main.rs:85:24:85:32 | file_path | provenance | Sink:MaD:6 | -| src/main.rs:80:21:80:29 | file_path | src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | provenance | MaD:15 | -| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | src/main.rs:80:21:80:53 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:80:21:80:29 | file_path | src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | provenance | MaD:18 | +| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | src/main.rs:80:21:80:53 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:80:21:80:53 | ... .unwrap() | src/main.rs:80:9:80:17 | file_path | provenance | | | src/main.rs:90:11:90:19 | file_path | src/main.rs:93:32:93:40 | file_path | provenance | | | src/main.rs:93:9:93:17 | file_path [&ref] | src/main.rs:98:21:98:29 | file_path [&ref] | provenance | | | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | src/main.rs:93:9:93:17 | file_path [&ref] | provenance | | -| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:13 | +| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:16 | | src/main.rs:93:32:93:40 | file_path | src/main.rs:93:31:93:40 | &file_path [&ref] | provenance | | | src/main.rs:98:9:98:17 | file_path | src/main.rs:99:24:99:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:98:21:98:29 | file_path [&ref] | src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | provenance | Config | -| src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | src/main.rs:98:21:98:53 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | src/main.rs:98:21:98:53 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:98:21:98:53 | ... .unwrap() | src/main.rs:98:9:98:17 | file_path | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:104:33:104:37 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:106:39:106:43 | path1 | provenance | | @@ -55,55 +57,65 @@ edges | src/main.rs:103:9:103:13 | path1 | src/main.rs:115:39:115:43 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:122:27:122:31 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:123:37:123:41 | path1 | provenance | | -| src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:7 | -| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:9 | -| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:10 | +| src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:9 | +| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:11 | +| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:13 | | src/main.rs:103:17:103:48 | ... .unwrap() | src/main.rs:103:9:103:13 | path1 | provenance | | -| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:8 | +| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:10 | | src/main.rs:104:33:104:45 | path1.clone() | src/main.rs:104:33:104:45 | path1.clone() | provenance | Sink:MaD:2 | | src/main.rs:106:9:106:13 | path2 | src/main.rs:107:33:107:37 | path2 | provenance | Sink:MaD:2 | -| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:106:17:106:61 | ... .unwrap() | src/main.rs:106:9:106:13 | path2 | provenance | | -| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:8 | +| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:10 | | src/main.rs:106:39:106:51 | path1.clone() | src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | provenance | Config | | src/main.rs:109:9:109:13 | path3 | src/main.rs:110:35:110:39 | path3 | provenance | Sink:MaD:4 | | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | src/main.rs:109:17:109:60 | await ... [Ok] | provenance | | -| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:109:17:109:69 | ... .unwrap() | src/main.rs:109:9:109:13 | path3 | provenance | | -| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:8 | +| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:10 | | src/main.rs:109:41:109:53 | path1.clone() | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | provenance | Config | | src/main.rs:112:9:112:13 | path4 | src/main.rs:113:39:113:43 | path4 | provenance | Sink:MaD:1 | | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | src/main.rs:112:17:112:64 | await ... [Ok] | provenance | | -| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:112:17:112:73 | ... .unwrap() | src/main.rs:112:9:112:13 | path4 | provenance | | -| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:8 | +| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:10 | | src/main.rs:112:45:112:57 | path1.clone() | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | provenance | Config | | src/main.rs:115:9:115:13 | path5 [&ref] | src/main.rs:116:33:116:37 | path5 | provenance | Sink:MaD:2 | | src/main.rs:115:9:115:13 | path5 [&ref] | src/main.rs:118:17:118:21 | path5 [&ref] | provenance | | | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | src/main.rs:115:9:115:13 | path5 [&ref] | provenance | | -| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:13 | +| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:16 | | src/main.rs:115:39:115:43 | path1 | src/main.rs:115:38:115:43 | &path1 [&ref] | provenance | | | src/main.rs:118:9:118:13 | path6 | src/main.rs:119:33:119:37 | path6 | provenance | Sink:MaD:2 | | src/main.rs:118:17:118:21 | path5 [&ref] | src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | provenance | Config | -| src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | src/main.rs:118:17:118:45 | ... .unwrap() | provenance | MaD:11 | +| src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | src/main.rs:118:17:118:45 | ... .unwrap() | provenance | MaD:14 | | src/main.rs:118:17:118:45 | ... .unwrap() | src/main.rs:118:9:118:13 | path6 | provenance | | -| src/main.rs:122:27:122:31 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:8 | +| src/main.rs:122:27:122:31 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:10 | | src/main.rs:122:27:122:39 | path1.clone() | src/main.rs:122:27:122:39 | path1.clone() | provenance | Sink:MaD:5 | -| src/main.rs:123:37:123:41 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:8 | +| src/main.rs:123:37:123:41 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:10 | | src/main.rs:123:37:123:49 | path1.clone() | src/main.rs:123:37:123:49 | path1.clone() | provenance | Sink:MaD:5 | | src/main.rs:170:16:170:29 | ...: ... [&ref] | src/main.rs:172:26:172:33 | path_str [&ref] | provenance | | | src/main.rs:170:16:170:29 | ...: ... [&ref] | src/main.rs:174:36:174:43 | path_str | provenance | Sink:MaD:2 | | src/main.rs:172:9:172:12 | path [&ref] | src/main.rs:173:8:173:11 | path | provenance | Sink:MaD:3 | | src/main.rs:172:9:172:12 | path [&ref] | src/main.rs:177:36:177:39 | path | provenance | Sink:MaD:2 | | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | src/main.rs:172:9:172:12 | path [&ref] | provenance | | -| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:13 | -| src/main.rs:185:9:185:13 | path1 | src/main.rs:186:18:186:22 | path1 | provenance | | -| src/main.rs:185:17:185:32 | ...::args(...) | src/main.rs:185:17:185:32 | ...::args(...) [element] | provenance | Src:MaD:7 | -| src/main.rs:185:17:185:32 | ...::args(...) [element] | src/main.rs:185:17:185:39 | ... .nth(...) [Some] | provenance | MaD:9 | -| src/main.rs:185:17:185:39 | ... .nth(...) [Some] | src/main.rs:185:17:185:48 | ... .unwrap() | provenance | MaD:10 | -| src/main.rs:185:17:185:48 | ... .unwrap() | src/main.rs:185:9:185:13 | path1 | provenance | | -| src/main.rs:186:17:186:22 | &path1 [&ref] | src/main.rs:170:16:170:29 | ...: ... [&ref] | provenance | | -| src/main.rs:186:18:186:22 | path1 | src/main.rs:186:17:186:22 | &path1 [&ref] | provenance | | +| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:16 | +| src/main.rs:191:23:191:55 | ...: State::<...> | src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | provenance | | +| src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | src/main.rs:192:74:192:79 | config | provenance | heuristic-callback | +| src/main.rs:192:73:192:84 | &... [&ref] | src/main.rs:192:73:192:84 | &... | provenance | Sink:MaD:6 | +| src/main.rs:192:74:192:79 | config | src/main.rs:192:74:192:84 | config.path | provenance | MaD:12 | +| src/main.rs:192:74:192:84 | config.path | src/main.rs:192:73:192:84 | &... [&ref] | provenance | | +| src/main.rs:200:18:200:41 | ...: Json::<...> | src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | provenance | | +| src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | src/main.rs:201:73:201:76 | path | provenance | heuristic-callback | +| src/main.rs:201:73:201:76 | path | src/main.rs:201:73:201:76 | path | provenance | Sink:MaD:6 | +| src/main.rs:206:37:206:48 | destructured | src/main.rs:191:23:191:55 | ...: State::<...> | provenance | Src:MaD:7 | +| src/main.rs:208:33:208:39 | request | src/main.rs:200:18:200:41 | ...: Json::<...> | provenance | Src:MaD:8 | +| src/main.rs:211:9:211:13 | path1 | src/main.rs:212:18:212:22 | path1 | provenance | | +| src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:211:17:211:32 | ...::args(...) [element] | provenance | Src:MaD:9 | +| src/main.rs:211:17:211:32 | ...::args(...) [element] | src/main.rs:211:17:211:39 | ... .nth(...) [Some] | provenance | MaD:11 | +| src/main.rs:211:17:211:39 | ... .nth(...) [Some] | src/main.rs:211:17:211:48 | ... .unwrap() | provenance | MaD:13 | +| src/main.rs:211:17:211:48 | ... .unwrap() | src/main.rs:211:9:211:13 | path1 | provenance | | +| src/main.rs:212:17:212:22 | &path1 [&ref] | src/main.rs:170:16:170:29 | ...: ... [&ref] | provenance | | +| src/main.rs:212:18:212:22 | path1 | src/main.rs:212:17:212:22 | &path1 [&ref] | provenance | | models | 1 | Sink: ::open; Argument[0]; path-injection | | 2 | Sink: ::open; Argument[0]; path-injection | @@ -111,15 +123,18 @@ models | 4 | Sink: ::open; Argument[0]; path-injection | | 5 | Sink: std::fs::copy; Argument[0,1]; path-injection | | 6 | Sink: std::fs::read_to_string; Argument[0]; path-injection | -| 7 | Source: std::env::args; ReturnValue.Element; commandargs | -| 8 | Summary: ::clone; Argument[self].Reference; ReturnValue; value | -| 9 | Summary: ::nth; Argument[self].Reference.Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 10 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 11 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 12 | Summary: ::join; Argument[0]; ReturnValue; taint | -| 13 | Summary: ::new; Argument[0].Reference; ReturnValue.Reference; value | -| 14 | Summary: ::from; Argument[0].Field[alloc::borrow::Cow::Owned(0)]; ReturnValue; value | -| 15 | Summary: ::deref; Argument[self].Reference.Field[std::path::PathBuf::inner]; ReturnValue.Reference; value | +| 7 | Source: axum::routing::method_routing::get; Argument[0].Parameter[0..7]; remote | +| 8 | Source: axum::routing::method_routing::post; Argument[0].Parameter[0..7]; remote | +| 9 | Source: std::env::args; ReturnValue.Element; commandargs | +| 10 | Summary: ::clone; Argument[self].Reference; ReturnValue; value | +| 11 | Summary: ::nth; Argument[self].Reference.Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 12 | Summary: ::deref; Argument[self].Reference; ReturnValue.Reference; taint | +| 13 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 14 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 15 | Summary: ::join; Argument[0]; ReturnValue; taint | +| 16 | Summary: ::new; Argument[0].Reference; ReturnValue.Reference; value | +| 17 | Summary: ::from; Argument[0].Field[alloc::borrow::Cow::Owned(0)]; ReturnValue; value | +| 18 | Summary: ::deref; Argument[self].Reference.Field[std::path::PathBuf::inner]; ReturnValue.Reference; value | nodes | src/main.rs:7:11:7:19 | file_name | semmle.label | file_name | | src/main.rs:9:9:9:17 | file_path | semmle.label | file_path | @@ -209,11 +224,23 @@ nodes | src/main.rs:173:8:173:11 | path | semmle.label | path | | src/main.rs:174:36:174:43 | path_str | semmle.label | path_str | | src/main.rs:177:36:177:39 | path | semmle.label | path | -| src/main.rs:185:9:185:13 | path1 | semmle.label | path1 | -| src/main.rs:185:17:185:32 | ...::args(...) | semmle.label | ...::args(...) | -| src/main.rs:185:17:185:32 | ...::args(...) [element] | semmle.label | ...::args(...) [element] | -| src/main.rs:185:17:185:39 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] | -| src/main.rs:185:17:185:48 | ... .unwrap() | semmle.label | ... .unwrap() | -| src/main.rs:186:17:186:22 | &path1 [&ref] | semmle.label | &path1 [&ref] | -| src/main.rs:186:18:186:22 | path1 | semmle.label | path1 | +| src/main.rs:191:23:191:55 | ...: State::<...> | semmle.label | ...: State::<...> | +| src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | semmle.label | \|...\| ... : ... => .. [captured config] | +| src/main.rs:192:73:192:84 | &... | semmle.label | &... | +| src/main.rs:192:73:192:84 | &... [&ref] | semmle.label | &... [&ref] | +| src/main.rs:192:74:192:79 | config | semmle.label | config | +| src/main.rs:192:74:192:84 | config.path | semmle.label | config.path | +| src/main.rs:200:18:200:41 | ...: Json::<...> | semmle.label | ...: Json::<...> | +| src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | semmle.label | \|...\| ... : ... => .. [captured path] | +| src/main.rs:201:73:201:76 | path | semmle.label | path | +| src/main.rs:201:73:201:76 | path | semmle.label | path | +| src/main.rs:206:37:206:48 | destructured | semmle.label | destructured | +| src/main.rs:208:33:208:39 | request | semmle.label | request | +| src/main.rs:211:9:211:13 | path1 | semmle.label | path1 | +| src/main.rs:211:17:211:32 | ...::args(...) | semmle.label | ...::args(...) | +| src/main.rs:211:17:211:32 | ...::args(...) [element] | semmle.label | ...::args(...) [element] | +| src/main.rs:211:17:211:39 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] | +| src/main.rs:211:17:211:48 | ... .unwrap() | semmle.label | ... .unwrap() | +| src/main.rs:212:17:212:22 | &path1 [&ref] | semmle.label | &path1 [&ref] | +| src/main.rs:212:18:212:22 | path1 | semmle.label | path1 | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-022/options.yml b/rust/ql/test/query-tests/security/CWE-022/options.yml index 18392052c7c5..2c0b985581ec 100644 --- a/rust/ql/test/query-tests/security/CWE-022/options.yml +++ b/rust/ql/test/query-tests/security/CWE-022/options.yml @@ -3,3 +3,4 @@ qltest_dependencies: - poem = { version = "3.1.7" } - tokio = { version = "1.43.0", features = ["full"] } - async-std = { version = "1.13.1" } + - axum = { version = "0.8.4" } \ No newline at end of file diff --git a/rust/ql/test/query-tests/security/CWE-022/src/main.rs b/rust/ql/test/query-tests/security/CWE-022/src/main.rs index f686fdf1d95b..bdc33b4d3764 100644 --- a/rust/ql/test/query-tests/security/CWE-022/src/main.rs +++ b/rust/ql/test/query-tests/security/CWE-022/src/main.rs @@ -181,7 +181,33 @@ fn my_function(path_str: &str) -> Result<(), std::io::Error> { Ok(()) } +use axum::{extract::State, routing::{get, post}, Json, Router}; +use std::sync::Arc; + +struct Config { + path: String, +} + +async fn destructured(State(config): State>) { + let _ = tokio::task::spawn_blocking(move || std::fs::read_to_string(&config.path)).await; // $ path-injection-sink $ SPURIOUS: Alert[rust/path-injection]=s1 +} + +async fn local_clone(state: State>) { + let config = Arc::clone(&state.0); + let _ = tokio::task::spawn_blocking(move || std::fs::read_to_string(&config.path)).await; // $ path-injection-sink +} + +async fn request(Json(path): Json) { + let _ = tokio::task::spawn_blocking(move || std::fs::read_to_string(path)).await; // $ Alert[rust/path-injection]=s3 path-injection-sink +} + fn main() { + let _: Router = Router::new() + .route("/destructured", get(destructured)) // $ SPURIOUS: Source=s1 + .route("/local-clone", get(local_clone)) + .route("/request", post(request)) // $ Source=s3 + .with_state(Arc::new(Config { path: String::from("configured-file") })); + let path1 = std::env::args().nth(1).unwrap(); // $ Source=arg2 my_function(&path1); } From cd08b226a5989eabeec4990f90c79f1befa2c455 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 29 Oct 2026 11:14:48 +0100 Subject: [PATCH 2/3] Rust: Add more captured variables flow tests --- .../dataflow/lambdas/inline-flow.expected | 311 +++++++++--------- .../library-tests/dataflow/lambdas/main.rs | 16 +- 2 files changed, 161 insertions(+), 166 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected index 6b9075dd7b0e..c5a1a18efe1a 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected @@ -6,71 +6,64 @@ edges | main.rs:22:9:22:9 | a | main.rs:23:13:23:13 | a | provenance | | | main.rs:22:13:22:22 | source(...) | main.rs:22:9:22:9 | a | provenance | | | main.rs:23:13:23:13 | a | main.rs:15:20:15:23 | ... | provenance | | -| main.rs:27:20:27:23 | ... | main.rs:27:26:27:52 | if cond {...} else {...} | provenance | | -| main.rs:28:9:28:9 | a | main.rs:29:21:29:21 | a | provenance | | -| main.rs:28:13:28:22 | source(...) | main.rs:28:9:28:9 | a | provenance | | -| main.rs:29:9:29:9 | b | main.rs:30:10:30:10 | b | provenance | | -| main.rs:29:13:29:22 | f(...) | main.rs:29:9:29:9 | b | provenance | | -| main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | provenance | | -| main.rs:29:21:29:21 | a | main.rs:29:13:29:22 | f(...) | provenance | | -| main.rs:37:16:37:25 | source(...) | main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | provenance | | -| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | main.rs:40:10:40:13 | capt | provenance | | -| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | main.rs:44:5:44:5 | g [captured capt] | provenance | | -| main.rs:44:5:44:5 | g [captured capt] | main.rs:42:14:42:17 | capt | provenance | | -| main.rs:47:29:49:1 | { ... } | main.rs:57:10:57:12 | f(...) | provenance | | -| main.rs:48:5:48:14 | source(...) | main.rs:47:29:49:1 | { ... } | provenance | | -| main.rs:51:17:51:25 | ...: i64 | main.rs:52:10:52:13 | data | provenance | | -| main.rs:62:9:62:9 | a | main.rs:63:7:63:7 | a | provenance | | -| main.rs:62:13:62:22 | source(...) | main.rs:62:9:62:9 | a | provenance | | -| main.rs:63:7:63:7 | a | main.rs:51:17:51:25 | ...: i64 | provenance | | -| main.rs:66:24:66:32 | ...: i64 | main.rs:66:42:72:1 | { ... } | provenance | | -| main.rs:76:9:76:9 | a | main.rs:77:21:77:21 | a | provenance | | -| main.rs:76:13:76:22 | source(...) | main.rs:76:9:76:9 | a | provenance | | -| main.rs:77:9:77:9 | b | main.rs:78:10:78:10 | b | provenance | | -| main.rs:77:13:77:22 | f(...) | main.rs:77:9:77:9 | b | provenance | | -| main.rs:77:21:77:21 | a | main.rs:66:24:66:32 | ...: i64 | provenance | | -| main.rs:77:21:77:21 | a | main.rs:77:13:77:22 | f(...) | provenance | | -| main.rs:81:28:81:33 | ...: i64 | main.rs:82:7:82:7 | x | provenance | | -| main.rs:81:28:81:33 | ...: i64 | main.rs:82:7:82:7 | x | provenance | | -| main.rs:81:28:81:33 | ...: i64 | main.rs:82:7:82:7 | x | provenance | | -| main.rs:82:7:82:7 | x | main.rs:87:12:87:12 | ... | provenance | | -| main.rs:82:7:82:7 | x | main.rs:89:12:89:12 | ... | provenance | | -| main.rs:82:7:82:7 | x | main.rs:99:17:99:17 | ... | provenance | | -| main.rs:82:7:82:7 | x | main.rs:101:17:101:17 | ... | provenance | | -| main.rs:86:9:86:9 | a | main.rs:87:24:87:24 | a | provenance | | -| main.rs:86:13:86:22 | source(...) | main.rs:86:9:86:9 | a | provenance | | -| main.rs:87:12:87:12 | ... | main.rs:87:20:87:20 | x | provenance | | -| main.rs:87:24:87:24 | a | main.rs:81:28:81:33 | ...: i64 | provenance | | -| main.rs:88:9:88:9 | b | main.rs:89:24:89:24 | b | provenance | | -| main.rs:88:13:88:22 | source(...) | main.rs:88:9:88:9 | b | provenance | | -| main.rs:89:12:89:12 | ... | main.rs:89:20:89:20 | x | provenance | | -| main.rs:89:24:89:24 | b | main.rs:81:28:81:33 | ...: i64 | provenance | | -| main.rs:93:33:93:38 | ...: i64 | main.rs:94:14:94:14 | x | provenance | | -| main.rs:94:14:94:14 | x | main.rs:81:28:81:33 | ...: i64 | provenance | | -| main.rs:98:9:98:9 | a | main.rs:99:29:99:29 | a | provenance | | -| main.rs:98:13:98:22 | source(...) | main.rs:98:9:98:9 | a | provenance | | -| main.rs:99:17:99:17 | ... | main.rs:99:25:99:25 | x | provenance | | -| main.rs:99:29:99:29 | a | main.rs:93:33:93:38 | ...: i64 | provenance | | -| main.rs:100:9:100:9 | b | main.rs:101:29:101:29 | b | provenance | | -| main.rs:100:13:100:22 | source(...) | main.rs:100:9:100:9 | b | provenance | | -| main.rs:101:17:101:17 | ... | main.rs:101:25:101:25 | x | provenance | | -| main.rs:101:29:101:29 | b | main.rs:93:33:93:38 | ...: i64 | provenance | | -| main.rs:109:13:109:22 | source(...) | main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:109:13:109:22 | source(...) | main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:109:13:109:22 | source(...) | main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:109:13:109:22 | source(...) | main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | main.rs:110:35:110:35 | a | provenance | heuristic-callback | -| main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | main.rs:111:35:111:35 | a | provenance | heuristic-callback | -| main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | main.rs:112:35:112:35 | a | provenance | heuristic-callback | -| main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | main.rs:113:35:113:35 | a | provenance | heuristic-callback | -| main.rs:120:30:120:40 | source(...) | main.rs:121:14:121:25 | await future | provenance | | -| main.rs:125:20:125:30 | source(...) | main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | provenance | | -| main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | main.rs:127:18:127:21 | data | provenance | | -| main.rs:133:20:133:30 | source(...) | main.rs:135:14:135:19 | future [captured data] | provenance | | -| main.rs:135:14:135:19 | future [captured data] | main.rs:134:30:134:33 | data | provenance | | -| main.rs:135:14:135:19 | future [captured data] | main.rs:135:14:135:25 | await future | provenance | | -| main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | main.rs:145:14:145:21 | captured | provenance | | -| main.rs:142:24:142:34 | source(...) | main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | provenance | | +| main.rs:48:16:48:25 | source(...) | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | provenance | | +| main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | main.rs:51:10:51:13 | capt | provenance | | +| main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | main.rs:55:5:55:5 | g [captured capt] | provenance | | +| main.rs:55:5:55:5 | g [captured capt] | main.rs:53:14:53:17 | capt | provenance | | +| main.rs:58:29:60:1 | { ... } | main.rs:68:10:68:12 | f(...) | provenance | | +| main.rs:59:5:59:14 | source(...) | main.rs:58:29:60:1 | { ... } | provenance | | +| main.rs:62:17:62:25 | ...: i64 | main.rs:63:10:63:13 | data | provenance | | +| main.rs:73:9:73:9 | a | main.rs:74:7:74:7 | a | provenance | | +| main.rs:73:13:73:22 | source(...) | main.rs:73:9:73:9 | a | provenance | | +| main.rs:74:7:74:7 | a | main.rs:62:17:62:25 | ...: i64 | provenance | | +| main.rs:77:24:77:32 | ...: i64 | main.rs:77:42:83:1 | { ... } | provenance | | +| main.rs:87:9:87:9 | a | main.rs:88:21:88:21 | a | provenance | | +| main.rs:87:13:87:22 | source(...) | main.rs:87:9:87:9 | a | provenance | | +| main.rs:88:9:88:9 | b | main.rs:89:10:89:10 | b | provenance | | +| main.rs:88:13:88:22 | f(...) | main.rs:88:9:88:9 | b | provenance | | +| main.rs:88:21:88:21 | a | main.rs:77:24:77:32 | ...: i64 | provenance | | +| main.rs:88:21:88:21 | a | main.rs:88:13:88:22 | f(...) | provenance | | +| main.rs:92:28:92:33 | ...: i64 | main.rs:93:7:93:7 | x | provenance | | +| main.rs:92:28:92:33 | ...: i64 | main.rs:93:7:93:7 | x | provenance | | +| main.rs:92:28:92:33 | ...: i64 | main.rs:93:7:93:7 | x | provenance | | +| main.rs:93:7:93:7 | x | main.rs:98:12:98:12 | ... | provenance | | +| main.rs:93:7:93:7 | x | main.rs:100:12:100:12 | ... | provenance | | +| main.rs:93:7:93:7 | x | main.rs:110:17:110:17 | ... | provenance | | +| main.rs:93:7:93:7 | x | main.rs:112:17:112:17 | ... | provenance | | +| main.rs:97:9:97:9 | a | main.rs:98:24:98:24 | a | provenance | | +| main.rs:97:13:97:22 | source(...) | main.rs:97:9:97:9 | a | provenance | | +| main.rs:98:12:98:12 | ... | main.rs:98:20:98:20 | x | provenance | | +| main.rs:98:24:98:24 | a | main.rs:92:28:92:33 | ...: i64 | provenance | | +| main.rs:99:9:99:9 | b | main.rs:100:24:100:24 | b | provenance | | +| main.rs:99:13:99:22 | source(...) | main.rs:99:9:99:9 | b | provenance | | +| main.rs:100:12:100:12 | ... | main.rs:100:20:100:20 | x | provenance | | +| main.rs:100:24:100:24 | b | main.rs:92:28:92:33 | ...: i64 | provenance | | +| main.rs:104:33:104:38 | ...: i64 | main.rs:105:14:105:14 | x | provenance | | +| main.rs:105:14:105:14 | x | main.rs:92:28:92:33 | ...: i64 | provenance | | +| main.rs:109:9:109:9 | a | main.rs:110:29:110:29 | a | provenance | | +| main.rs:109:13:109:22 | source(...) | main.rs:109:9:109:9 | a | provenance | | +| main.rs:110:17:110:17 | ... | main.rs:110:25:110:25 | x | provenance | | +| main.rs:110:29:110:29 | a | main.rs:104:33:104:38 | ...: i64 | provenance | | +| main.rs:111:9:111:9 | b | main.rs:112:29:112:29 | b | provenance | | +| main.rs:111:13:111:22 | source(...) | main.rs:111:9:111:9 | b | provenance | | +| main.rs:112:17:112:17 | ... | main.rs:112:25:112:25 | x | provenance | | +| main.rs:112:29:112:29 | b | main.rs:104:33:104:38 | ...: i64 | provenance | | +| main.rs:120:13:120:22 | source(...) | main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:13:120:22 | source(...) | main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:13:120:22 | source(...) | main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:13:120:22 | source(...) | main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | main.rs:121:35:121:35 | a | provenance | heuristic-callback | +| main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | main.rs:122:35:122:35 | a | provenance | heuristic-callback | +| main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | main.rs:123:35:123:35 | a | provenance | heuristic-callback | +| main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | main.rs:124:35:124:35 | a | provenance | heuristic-callback | +| main.rs:131:30:131:40 | source(...) | main.rs:132:14:132:25 | await future | provenance | | +| main.rs:136:20:136:30 | source(...) | main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | provenance | | +| main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | main.rs:138:18:138:21 | data | provenance | | +| main.rs:144:20:144:30 | source(...) | main.rs:146:14:146:19 | future [captured data] | provenance | | +| main.rs:146:14:146:19 | future [captured data] | main.rs:145:30:145:33 | data | provenance | | +| main.rs:146:14:146:19 | future [captured data] | main.rs:146:14:146:25 | await future | provenance | | +| main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | main.rs:156:14:156:21 | captured | provenance | | +| main.rs:153:24:153:34 | source(...) | main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | provenance | | nodes | main.rs:10:20:10:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | | main.rs:10:30:10:39 | source(...) | semmle.label | source(...) | @@ -80,109 +73,99 @@ nodes | main.rs:22:9:22:9 | a | semmle.label | a | | main.rs:22:13:22:22 | source(...) | semmle.label | source(...) | | main.rs:23:13:23:13 | a | semmle.label | a | -| main.rs:27:20:27:23 | ... | semmle.label | ... | -| main.rs:27:26:27:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | -| main.rs:28:9:28:9 | a | semmle.label | a | -| main.rs:28:13:28:22 | source(...) | semmle.label | source(...) | -| main.rs:29:9:29:9 | b | semmle.label | b | -| main.rs:29:13:29:22 | f(...) | semmle.label | f(...) | -| main.rs:29:21:29:21 | a | semmle.label | a | -| main.rs:30:10:30:10 | b | semmle.label | b | -| main.rs:37:16:37:25 | source(...) | semmle.label | source(...) | -| main.rs:39:5:39:5 | [post] f : ... => .. [captured capt] | semmle.label | [post] f : ... => .. [captured capt] | -| main.rs:40:10:40:13 | capt | semmle.label | capt | -| main.rs:42:14:42:17 | capt | semmle.label | capt | -| main.rs:44:5:44:5 | g [captured capt] | semmle.label | g [captured capt] | -| main.rs:47:29:49:1 | { ... } | semmle.label | { ... } | -| main.rs:48:5:48:14 | source(...) | semmle.label | source(...) | -| main.rs:51:17:51:25 | ...: i64 | semmle.label | ...: i64 | -| main.rs:52:10:52:13 | data | semmle.label | data | -| main.rs:57:10:57:12 | f(...) | semmle.label | f(...) | -| main.rs:62:9:62:9 | a | semmle.label | a | -| main.rs:62:13:62:22 | source(...) | semmle.label | source(...) | -| main.rs:63:7:63:7 | a | semmle.label | a | -| main.rs:66:24:66:32 | ...: i64 | semmle.label | ...: i64 | -| main.rs:66:42:72:1 | { ... } | semmle.label | { ... } | -| main.rs:76:9:76:9 | a | semmle.label | a | -| main.rs:76:13:76:22 | source(...) | semmle.label | source(...) | -| main.rs:77:9:77:9 | b | semmle.label | b | -| main.rs:77:13:77:22 | f(...) | semmle.label | f(...) | -| main.rs:77:21:77:21 | a | semmle.label | a | -| main.rs:78:10:78:10 | b | semmle.label | b | -| main.rs:81:28:81:33 | ...: i64 | semmle.label | ...: i64 | -| main.rs:81:28:81:33 | ...: i64 | semmle.label | ...: i64 | -| main.rs:81:28:81:33 | ...: i64 | semmle.label | ...: i64 | -| main.rs:82:7:82:7 | x | semmle.label | x | -| main.rs:82:7:82:7 | x | semmle.label | x | -| main.rs:82:7:82:7 | x | semmle.label | x | -| main.rs:86:9:86:9 | a | semmle.label | a | -| main.rs:86:13:86:22 | source(...) | semmle.label | source(...) | -| main.rs:87:12:87:12 | ... | semmle.label | ... | -| main.rs:87:20:87:20 | x | semmle.label | x | -| main.rs:87:24:87:24 | a | semmle.label | a | +| main.rs:48:16:48:25 | source(...) | semmle.label | source(...) | +| main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | semmle.label | [post] f : ... => .. [captured capt] | +| main.rs:51:10:51:13 | capt | semmle.label | capt | +| main.rs:53:14:53:17 | capt | semmle.label | capt | +| main.rs:55:5:55:5 | g [captured capt] | semmle.label | g [captured capt] | +| main.rs:58:29:60:1 | { ... } | semmle.label | { ... } | +| main.rs:59:5:59:14 | source(...) | semmle.label | source(...) | +| main.rs:62:17:62:25 | ...: i64 | semmle.label | ...: i64 | +| main.rs:63:10:63:13 | data | semmle.label | data | +| main.rs:68:10:68:12 | f(...) | semmle.label | f(...) | +| main.rs:73:9:73:9 | a | semmle.label | a | +| main.rs:73:13:73:22 | source(...) | semmle.label | source(...) | +| main.rs:74:7:74:7 | a | semmle.label | a | +| main.rs:77:24:77:32 | ...: i64 | semmle.label | ...: i64 | +| main.rs:77:42:83:1 | { ... } | semmle.label | { ... } | +| main.rs:87:9:87:9 | a | semmle.label | a | +| main.rs:87:13:87:22 | source(...) | semmle.label | source(...) | | main.rs:88:9:88:9 | b | semmle.label | b | -| main.rs:88:13:88:22 | source(...) | semmle.label | source(...) | -| main.rs:89:12:89:12 | ... | semmle.label | ... | -| main.rs:89:20:89:20 | x | semmle.label | x | -| main.rs:89:24:89:24 | b | semmle.label | b | -| main.rs:93:33:93:38 | ...: i64 | semmle.label | ...: i64 | -| main.rs:94:14:94:14 | x | semmle.label | x | -| main.rs:98:9:98:9 | a | semmle.label | a | -| main.rs:98:13:98:22 | source(...) | semmle.label | source(...) | -| main.rs:99:17:99:17 | ... | semmle.label | ... | -| main.rs:99:25:99:25 | x | semmle.label | x | -| main.rs:99:29:99:29 | a | semmle.label | a | -| main.rs:100:9:100:9 | b | semmle.label | b | -| main.rs:100:13:100:22 | source(...) | semmle.label | source(...) | -| main.rs:101:17:101:17 | ... | semmle.label | ... | -| main.rs:101:25:101:25 | x | semmle.label | x | -| main.rs:101:29:101:29 | b | semmle.label | b | +| main.rs:88:13:88:22 | f(...) | semmle.label | f(...) | +| main.rs:88:21:88:21 | a | semmle.label | a | +| main.rs:89:10:89:10 | b | semmle.label | b | +| main.rs:92:28:92:33 | ...: i64 | semmle.label | ...: i64 | +| main.rs:92:28:92:33 | ...: i64 | semmle.label | ...: i64 | +| main.rs:92:28:92:33 | ...: i64 | semmle.label | ...: i64 | +| main.rs:93:7:93:7 | x | semmle.label | x | +| main.rs:93:7:93:7 | x | semmle.label | x | +| main.rs:93:7:93:7 | x | semmle.label | x | +| main.rs:97:9:97:9 | a | semmle.label | a | +| main.rs:97:13:97:22 | source(...) | semmle.label | source(...) | +| main.rs:98:12:98:12 | ... | semmle.label | ... | +| main.rs:98:20:98:20 | x | semmle.label | x | +| main.rs:98:24:98:24 | a | semmle.label | a | +| main.rs:99:9:99:9 | b | semmle.label | b | +| main.rs:99:13:99:22 | source(...) | semmle.label | source(...) | +| main.rs:100:12:100:12 | ... | semmle.label | ... | +| main.rs:100:20:100:20 | x | semmle.label | x | +| main.rs:100:24:100:24 | b | semmle.label | b | +| main.rs:104:33:104:38 | ...: i64 | semmle.label | ...: i64 | +| main.rs:105:14:105:14 | x | semmle.label | x | +| main.rs:109:9:109:9 | a | semmle.label | a | | main.rs:109:13:109:22 | source(...) | semmle.label | source(...) | -| main.rs:110:26:110:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | -| main.rs:110:35:110:35 | a | semmle.label | a | -| main.rs:111:26:111:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | -| main.rs:111:35:111:35 | a | semmle.label | a | -| main.rs:112:26:112:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | -| main.rs:112:35:112:35 | a | semmle.label | a | -| main.rs:113:26:113:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | -| main.rs:113:35:113:35 | a | semmle.label | a | -| main.rs:120:30:120:40 | source(...) | semmle.label | source(...) | -| main.rs:121:14:121:25 | await future | semmle.label | await future | -| main.rs:125:20:125:30 | source(...) | semmle.label | source(...) | -| main.rs:126:9:128:9 | { ... } : ... => .. [captured data] | semmle.label | { ... } : ... => .. [captured data] | -| main.rs:127:18:127:21 | data | semmle.label | data | -| main.rs:133:20:133:30 | source(...) | semmle.label | source(...) | -| main.rs:134:30:134:33 | data | semmle.label | data | -| main.rs:135:14:135:19 | future [captured data] | semmle.label | future [captured data] | -| main.rs:135:14:135:25 | await future | semmle.label | await future | -| main.rs:141:9:143:9 | [post] { ... } : ... => .. [captured captured] | semmle.label | [post] { ... } : ... => .. [captured captured] | -| main.rs:142:24:142:34 | source(...) | semmle.label | source(...) | -| main.rs:145:14:145:21 | captured | semmle.label | captured | +| main.rs:110:17:110:17 | ... | semmle.label | ... | +| main.rs:110:25:110:25 | x | semmle.label | x | +| main.rs:110:29:110:29 | a | semmle.label | a | +| main.rs:111:9:111:9 | b | semmle.label | b | +| main.rs:111:13:111:22 | source(...) | semmle.label | source(...) | +| main.rs:112:17:112:17 | ... | semmle.label | ... | +| main.rs:112:25:112:25 | x | semmle.label | x | +| main.rs:112:29:112:29 | b | semmle.label | b | +| main.rs:120:13:120:22 | source(...) | semmle.label | source(...) | +| main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | +| main.rs:121:35:121:35 | a | semmle.label | a | +| main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | +| main.rs:122:35:122:35 | a | semmle.label | a | +| main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | +| main.rs:123:35:123:35 | a | semmle.label | a | +| main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | +| main.rs:124:35:124:35 | a | semmle.label | a | +| main.rs:131:30:131:40 | source(...) | semmle.label | source(...) | +| main.rs:132:14:132:25 | await future | semmle.label | await future | +| main.rs:136:20:136:30 | source(...) | semmle.label | source(...) | +| main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | semmle.label | { ... } : ... => .. [captured data] | +| main.rs:138:18:138:21 | data | semmle.label | data | +| main.rs:144:20:144:30 | source(...) | semmle.label | source(...) | +| main.rs:145:30:145:33 | data | semmle.label | data | +| main.rs:146:14:146:19 | future [captured data] | semmle.label | future [captured data] | +| main.rs:146:14:146:25 | await future | semmle.label | await future | +| main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | semmle.label | [post] { ... } : ... => .. [captured captured] | +| main.rs:153:24:153:34 | source(...) | semmle.label | source(...) | +| main.rs:156:14:156:21 | captured | semmle.label | captured | subpaths -| main.rs:29:21:29:21 | a | main.rs:27:20:27:23 | ... | main.rs:27:26:27:52 | if cond {...} else {...} | main.rs:29:13:29:22 | f(...) | -| main.rs:77:21:77:21 | a | main.rs:66:24:66:32 | ...: i64 | main.rs:66:42:72:1 | { ... } | main.rs:77:13:77:22 | f(...) | -| main.rs:135:14:135:19 | future [captured data] | main.rs:134:30:134:33 | data | main.rs:134:30:134:33 | data | main.rs:135:14:135:25 | await future | +| main.rs:88:21:88:21 | a | main.rs:77:24:77:32 | ...: i64 | main.rs:77:42:83:1 | { ... } | main.rs:88:13:88:22 | f(...) | +| main.rs:146:14:146:19 | future [captured data] | main.rs:145:30:145:33 | data | main.rs:145:30:145:33 | data | main.rs:146:14:146:25 | await future | testFailures #select | main.rs:11:10:11:16 | f(...) | main.rs:10:30:10:39 | source(...) | main.rs:11:10:11:16 | f(...) | $@ | main.rs:10:30:10:39 | source(...) | source(...) | | main.rs:17:18:17:21 | data | main.rs:22:13:22:22 | source(...) | main.rs:17:18:17:21 | data | $@ | main.rs:22:13:22:22 | source(...) | source(...) | -| main.rs:30:10:30:10 | b | main.rs:28:13:28:22 | source(...) | main.rs:30:10:30:10 | b | $@ | main.rs:28:13:28:22 | source(...) | source(...) | -| main.rs:40:10:40:13 | capt | main.rs:37:16:37:25 | source(...) | main.rs:40:10:40:13 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | -| main.rs:42:14:42:17 | capt | main.rs:37:16:37:25 | source(...) | main.rs:42:14:42:17 | capt | $@ | main.rs:37:16:37:25 | source(...) | source(...) | -| main.rs:52:10:52:13 | data | main.rs:62:13:62:22 | source(...) | main.rs:52:10:52:13 | data | $@ | main.rs:62:13:62:22 | source(...) | source(...) | -| main.rs:57:10:57:12 | f(...) | main.rs:48:5:48:14 | source(...) | main.rs:57:10:57:12 | f(...) | $@ | main.rs:48:5:48:14 | source(...) | source(...) | -| main.rs:78:10:78:10 | b | main.rs:76:13:76:22 | source(...) | main.rs:78:10:78:10 | b | $@ | main.rs:76:13:76:22 | source(...) | source(...) | -| main.rs:87:20:87:20 | x | main.rs:86:13:86:22 | source(...) | main.rs:87:20:87:20 | x | $@ | main.rs:86:13:86:22 | source(...) | source(...) | -| main.rs:89:20:89:20 | x | main.rs:88:13:88:22 | source(...) | main.rs:89:20:89:20 | x | $@ | main.rs:88:13:88:22 | source(...) | source(...) | -| main.rs:99:25:99:25 | x | main.rs:98:13:98:22 | source(...) | main.rs:99:25:99:25 | x | $@ | main.rs:98:13:98:22 | source(...) | source(...) | -| main.rs:99:25:99:25 | x | main.rs:100:13:100:22 | source(...) | main.rs:99:25:99:25 | x | $@ | main.rs:100:13:100:22 | source(...) | source(...) | -| main.rs:101:25:101:25 | x | main.rs:98:13:98:22 | source(...) | main.rs:101:25:101:25 | x | $@ | main.rs:98:13:98:22 | source(...) | source(...) | -| main.rs:101:25:101:25 | x | main.rs:100:13:100:22 | source(...) | main.rs:101:25:101:25 | x | $@ | main.rs:100:13:100:22 | source(...) | source(...) | -| main.rs:110:35:110:35 | a | main.rs:109:13:109:22 | source(...) | main.rs:110:35:110:35 | a | $@ | main.rs:109:13:109:22 | source(...) | source(...) | -| main.rs:111:35:111:35 | a | main.rs:109:13:109:22 | source(...) | main.rs:111:35:111:35 | a | $@ | main.rs:109:13:109:22 | source(...) | source(...) | -| main.rs:112:35:112:35 | a | main.rs:109:13:109:22 | source(...) | main.rs:112:35:112:35 | a | $@ | main.rs:109:13:109:22 | source(...) | source(...) | -| main.rs:113:35:113:35 | a | main.rs:109:13:109:22 | source(...) | main.rs:113:35:113:35 | a | $@ | main.rs:109:13:109:22 | source(...) | source(...) | -| main.rs:121:14:121:25 | await future | main.rs:120:30:120:40 | source(...) | main.rs:121:14:121:25 | await future | $@ | main.rs:120:30:120:40 | source(...) | source(...) | -| main.rs:127:18:127:21 | data | main.rs:125:20:125:30 | source(...) | main.rs:127:18:127:21 | data | $@ | main.rs:125:20:125:30 | source(...) | source(...) | -| main.rs:135:14:135:25 | await future | main.rs:133:20:133:30 | source(...) | main.rs:135:14:135:25 | await future | $@ | main.rs:133:20:133:30 | source(...) | source(...) | -| main.rs:145:14:145:21 | captured | main.rs:142:24:142:34 | source(...) | main.rs:145:14:145:21 | captured | $@ | main.rs:142:24:142:34 | source(...) | source(...) | +| main.rs:51:10:51:13 | capt | main.rs:48:16:48:25 | source(...) | main.rs:51:10:51:13 | capt | $@ | main.rs:48:16:48:25 | source(...) | source(...) | +| main.rs:53:14:53:17 | capt | main.rs:48:16:48:25 | source(...) | main.rs:53:14:53:17 | capt | $@ | main.rs:48:16:48:25 | source(...) | source(...) | +| main.rs:63:10:63:13 | data | main.rs:73:13:73:22 | source(...) | main.rs:63:10:63:13 | data | $@ | main.rs:73:13:73:22 | source(...) | source(...) | +| main.rs:68:10:68:12 | f(...) | main.rs:59:5:59:14 | source(...) | main.rs:68:10:68:12 | f(...) | $@ | main.rs:59:5:59:14 | source(...) | source(...) | +| main.rs:89:10:89:10 | b | main.rs:87:13:87:22 | source(...) | main.rs:89:10:89:10 | b | $@ | main.rs:87:13:87:22 | source(...) | source(...) | +| main.rs:98:20:98:20 | x | main.rs:97:13:97:22 | source(...) | main.rs:98:20:98:20 | x | $@ | main.rs:97:13:97:22 | source(...) | source(...) | +| main.rs:100:20:100:20 | x | main.rs:99:13:99:22 | source(...) | main.rs:100:20:100:20 | x | $@ | main.rs:99:13:99:22 | source(...) | source(...) | +| main.rs:110:25:110:25 | x | main.rs:109:13:109:22 | source(...) | main.rs:110:25:110:25 | x | $@ | main.rs:109:13:109:22 | source(...) | source(...) | +| main.rs:110:25:110:25 | x | main.rs:111:13:111:22 | source(...) | main.rs:110:25:110:25 | x | $@ | main.rs:111:13:111:22 | source(...) | source(...) | +| main.rs:112:25:112:25 | x | main.rs:109:13:109:22 | source(...) | main.rs:112:25:112:25 | x | $@ | main.rs:109:13:109:22 | source(...) | source(...) | +| main.rs:112:25:112:25 | x | main.rs:111:13:111:22 | source(...) | main.rs:112:25:112:25 | x | $@ | main.rs:111:13:111:22 | source(...) | source(...) | +| main.rs:121:35:121:35 | a | main.rs:120:13:120:22 | source(...) | main.rs:121:35:121:35 | a | $@ | main.rs:120:13:120:22 | source(...) | source(...) | +| main.rs:122:35:122:35 | a | main.rs:120:13:120:22 | source(...) | main.rs:122:35:122:35 | a | $@ | main.rs:120:13:120:22 | source(...) | source(...) | +| main.rs:123:35:123:35 | a | main.rs:120:13:120:22 | source(...) | main.rs:123:35:123:35 | a | $@ | main.rs:120:13:120:22 | source(...) | source(...) | +| main.rs:124:35:124:35 | a | main.rs:120:13:120:22 | source(...) | main.rs:124:35:124:35 | a | $@ | main.rs:120:13:120:22 | source(...) | source(...) | +| main.rs:132:14:132:25 | await future | main.rs:131:30:131:40 | source(...) | main.rs:132:14:132:25 | await future | $@ | main.rs:131:30:131:40 | source(...) | source(...) | +| main.rs:138:18:138:21 | data | main.rs:136:20:136:30 | source(...) | main.rs:138:18:138:21 | data | $@ | main.rs:136:20:136:30 | source(...) | source(...) | +| main.rs:146:14:146:25 | await future | main.rs:144:20:144:30 | source(...) | main.rs:146:14:146:25 | await future | $@ | main.rs:144:20:144:30 | source(...) | source(...) | +| main.rs:156:14:156:21 | captured | main.rs:153:24:153:34 | source(...) | main.rs:156:14:156:21 | captured | $@ | main.rs:153:24:153:34 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/lambdas/main.rs b/rust/ql/test/library-tests/dataflow/lambdas/main.rs index 650734bdd149..cbbadacb0b2f 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/main.rs +++ b/rust/ql/test/library-tests/dataflow/lambdas/main.rs @@ -23,11 +23,22 @@ fn closure_flow_in() { f(true, a); } +fn closure_flow_in2() { + let (mut x, y) = (source(1), 0); + (x) = x; + (|| sink(x))(); // $ MISSING: hasValueFlow=1 +} + +fn closure_flow_in3() { + let (ref x,) = (source(1),); + (|| sink(*x))(); // $ MISSING: hasValueFlow=1 +} + fn closure_flow_through() { - let f = |cond, data| if cond { data } else { 0 }; + let f = |cond, ((data))| if cond { data } else { 0 }; let a = source(43); let b = f(true, a); - sink(b); // $ hasValueFlow=43 + sink(b); // $ MISSING: hasValueFlow=43 } fn closure_captured_variable() { @@ -171,6 +182,7 @@ mod async_blocks { fn main() { closure_flow_out(); closure_flow_in(); + closure_flow_in2(); closure_flow_through(); closure_captured_variable(); function_flow_in(); From 6afe53364c66b512b12965bf1be265dea687dcb2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 28 Oct 2026 15:14:56 +0100 Subject: [PATCH 3/3] Rust: Fixes to flow through captured variables --- .../rust/dataflow/internal/DataFlowImpl.qll | 49 +++++----- .../rust/elements/internal/VariableImpl.qll | 15 ++- .../internal/typeinference/TypeInference.qll | 2 +- .../dataflow/lambdas/inline-flow.expected | 70 ++++++++++++-- .../library-tests/dataflow/lambdas/main.rs | 6 +- .../dataflow/local/DataFlowStep.expected | 2 +- .../dataflow/models/models.expected | 8 +- .../security/CWE-022/TaintedPath.expected | 94 ++++++++----------- .../query-tests/security/CWE-022/src/main.rs | 4 +- 9 files changed, 154 insertions(+), 96 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 60ec0fca820f..d6cf5aac1f95 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -11,6 +11,7 @@ private import rust private import SsaImpl as SsaImpl private import codeql.rust.controlflow.internal.Scope as Scope private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl +private import codeql.rust.elements.internal.VariableImpl::Impl as VariableImpl private import codeql.rust.internal.PathResolution private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.dataflow.Ssa @@ -230,7 +231,16 @@ module LocalFlow { nodeTo.asPat() = match.getAnArm().getPat() ) or - nodeFrom.asExpr() = nodeTo.asExpr().(ParenExpr).getExpr() + exists(ParenExpr pe, Expr e | + e = pe.getExpr() and + if VariableImpl::assignmentOperationDescendant(_, pe) + then nodeTo.asExpr() = e and nodeFrom.asExpr() = pe + else ( + nodeFrom.asExpr() = e and nodeTo.asExpr() = pe + ) + ) + or + nodeTo.asPat() = nodeFrom.asPat().(ParenPat).getPat() } pragma[nomagic] @@ -1070,43 +1080,36 @@ module VariableCapture { final class CapturedParameter extends CapturedVariable { ParamBase p; - CapturedParameter() { p = this.getParameter() } + CapturedParameter() { this.isParameter(p) } SourceParameterNode getParameterNode() { result.getParameter() = p } } class Expr extends AstNode { - predicate hasCfgNode(BasicBlocks::BasicBlock bb, int i) { this = bb.getNode(i).getAstNode() } + predicate hasCfgNode(BasicBlocks::BasicBlock bb, int i) { + this = bb.getNode(i).getAstNode() + or + this.(ParenExpr).getExpr().(Expr).hasCfgNode(bb, i) + } } class VariableWrite extends Expr { - Expr source; CapturedVariable v; VariableWrite() { - exists(AssignmentExpr assign, Variable::VariableWriteAccess write | - this = assign and - v = write.getVariable() and - assign.getLhs() = write and - assign.getRhs() = source - ) + this = v.getName() or - this = - any(LetStmt ls | - v.getPat() = ls.getPat() and - ls.getInitializer() = source - ) + v = this.(Variable::VariableWriteAccess).getVariable() + } + + override predicate hasCfgNode(BasicBlocks::BasicBlock bb, int i) { + not this instanceof VariableWriteAccess and + super.hasCfgNode(bb, i) or - this = - any(LetExpr le | - v.getPat() = le.getPat() and - le.getScrutinee() = source - ) + this.(VariableWriteAccess).getAssignmentExpr() = bb.getNode(i).getAstNode() } CapturedVariable getVariable() { result = v } - - Expr getSource() { result = source } } class VariableRead extends Expr { @@ -1145,7 +1148,7 @@ module VariableCapture { or result.(Flow::ExprNode).getExpr() = n.asExpr() or - result.(Flow::VariableWriteSourceNode).getVariableWrite().getSource() = n.asExpr() + result.(Flow::VariableWriteSourceNode).getVariableWrite() = n.getAstNode() or result.(Flow::ExprPostUpdateNode).getExpr() = n.(PostUpdateNode).getPreUpdateNode().asExpr() or diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 80f2259623bb..0c2c6b158212 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -310,7 +310,12 @@ module Impl { /** Holds if this variable is captured. */ predicate isCaptured() { this.getAnAccess().isCapture() } - /** Gets the parameter that introduces this variable, if any. */ + /** + * Gets the parameter that introduces this variable, if any. + * + * Note that this variable need not be a direct parameter; it could + * also be introduced through a destructuring pattern. + */ cached ParamBase getParameter() { CachedStage::ref() and @@ -319,6 +324,14 @@ module Impl { result.(Param).getPat() = getAPatAncestor*(this.getPat()) } + /** Holds if this variable corresponds directly to the parameter `p`. */ + predicate isParameter(ParamBase p) { + CachedStage::ref() and + p = this.getSelfParam() + or + p.(Param).getPat() = this.getPat() + } + /** Holds if this variable is mutable. */ predicate isMutable() { this.getPat().isMut() or this.getSelfParam().isMut() } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index 7f3a0ae0c282..0e71f878c08f 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -2348,7 +2348,7 @@ private module Input3 implements InputSig3 { AstNode getDefiningNode() { result = this.asLocalVariable().getPat().getName() or - result = this.asLocalVariable().getParameter().(SelfParam) or + this.asLocalVariable().isParameter(result.(SelfParam)) or result = this.asConst().getName() or result = this.asStatic().getName() } diff --git a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected index c5a1a18efe1a..51c5ef20566c 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/lambdas/inline-flow.expected @@ -1,4 +1,5 @@ models +| 1 | Summary: <& as core::ops::deref::Deref>::deref; Argument[self].Reference; ReturnValue; value | edges | main.rs:10:20:10:52 | if cond {...} else {...} | main.rs:11:10:11:16 | f(...) | provenance | | | main.rs:10:30:10:39 | source(...) | main.rs:10:20:10:52 | if cond {...} else {...} | provenance | | @@ -6,7 +7,26 @@ edges | main.rs:22:9:22:9 | a | main.rs:23:13:23:13 | a | provenance | | | main.rs:22:13:22:22 | source(...) | main.rs:22:9:22:9 | a | provenance | | | main.rs:23:13:23:13 | a | main.rs:15:20:15:23 | ... | provenance | | -| main.rs:48:16:48:25 | source(...) | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | provenance | | +| main.rs:27:9:27:18 | TuplePat [tuple.0] | main.rs:27:10:27:14 | mut x | provenance | | +| main.rs:27:10:27:14 | mut x | main.rs:28:6:28:6 | x | provenance | | +| main.rs:27:22:27:35 | TupleExpr [tuple.0] | main.rs:27:9:27:18 | TuplePat [tuple.0] | provenance | | +| main.rs:27:23:27:31 | source(...) | main.rs:27:22:27:35 | TupleExpr [tuple.0] | provenance | | +| main.rs:28:6:28:6 | x | main.rs:29:14:29:14 | x | provenance | | +| main.rs:33:9:33:16 | TuplePat [tuple.0] | main.rs:33:10:33:14 | ref x | provenance | | +| main.rs:33:10:33:14 | ref x | main.rs:33:14:33:14 | x [&ref] | provenance | | +| main.rs:33:14:33:14 | x [&ref] | main.rs:34:15:34:15 | x [&ref] | provenance | | +| main.rs:33:20:33:31 | TupleExpr [tuple.0] | main.rs:33:9:33:16 | TuplePat [tuple.0] | provenance | | +| main.rs:33:21:33:29 | source(...) | main.rs:33:20:33:31 | TupleExpr [tuple.0] | provenance | | +| main.rs:34:15:34:15 | x [&ref] | main.rs:34:14:34:15 | * ... | provenance | MaD:1 | +| main.rs:38:20:38:27 | ... | main.rs:38:30:38:56 | if cond {...} else {...} | provenance | | +| main.rs:39:9:39:9 | a | main.rs:40:21:40:21 | a | provenance | | +| main.rs:39:13:39:22 | source(...) | main.rs:39:9:39:9 | a | provenance | | +| main.rs:40:9:40:9 | b | main.rs:41:10:41:10 | b | provenance | | +| main.rs:40:13:40:22 | f(...) | main.rs:40:9:40:9 | b | provenance | | +| main.rs:40:21:40:21 | a | main.rs:38:20:38:27 | ... | provenance | | +| main.rs:40:21:40:21 | a | main.rs:40:13:40:22 | f(...) | provenance | | +| main.rs:48:9:48:12 | capt | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | provenance | | +| main.rs:48:16:48:25 | source(...) | main.rs:48:9:48:12 | capt | provenance | | | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | main.rs:51:10:51:13 | capt | provenance | | | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | main.rs:55:5:55:5 | g [captured capt] | provenance | | | main.rs:55:5:55:5 | g [captured capt] | main.rs:53:14:53:17 | capt | provenance | | @@ -48,22 +68,26 @@ edges | main.rs:111:13:111:22 | source(...) | main.rs:111:9:111:9 | b | provenance | | | main.rs:112:17:112:17 | ... | main.rs:112:25:112:25 | x | provenance | | | main.rs:112:29:112:29 | b | main.rs:104:33:104:38 | ...: i64 | provenance | | -| main.rs:120:13:120:22 | source(...) | main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:120:13:120:22 | source(...) | main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:120:13:120:22 | source(...) | main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | provenance | | -| main.rs:120:13:120:22 | source(...) | main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:9:120:9 | a | main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:9:120:9 | a | main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:9:120:9 | a | main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:9:120:9 | a | main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | provenance | | +| main.rs:120:13:120:22 | source(...) | main.rs:120:9:120:9 | a | provenance | | | main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | main.rs:121:35:121:35 | a | provenance | heuristic-callback | | main.rs:122:26:122:36 | \|...\| ... : ... => .. [captured a] | main.rs:122:35:122:35 | a | provenance | heuristic-callback | | main.rs:123:26:123:36 | \|...\| ... : ... => .. [captured a] | main.rs:123:35:123:35 | a | provenance | heuristic-callback | | main.rs:124:26:124:36 | \|...\| ... : ... => .. [captured a] | main.rs:124:35:124:35 | a | provenance | heuristic-callback | | main.rs:131:30:131:40 | source(...) | main.rs:132:14:132:25 | await future | provenance | | -| main.rs:136:20:136:30 | source(...) | main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | provenance | | +| main.rs:136:13:136:16 | data | main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | provenance | | +| main.rs:136:20:136:30 | source(...) | main.rs:136:13:136:16 | data | provenance | | | main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | main.rs:138:18:138:21 | data | provenance | | -| main.rs:144:20:144:30 | source(...) | main.rs:146:14:146:19 | future [captured data] | provenance | | +| main.rs:144:13:144:16 | data | main.rs:146:14:146:19 | future [captured data] | provenance | | +| main.rs:144:20:144:30 | source(...) | main.rs:144:13:144:16 | data | provenance | | | main.rs:146:14:146:19 | future [captured data] | main.rs:145:30:145:33 | data | provenance | | | main.rs:146:14:146:19 | future [captured data] | main.rs:146:14:146:25 | await future | provenance | | | main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | main.rs:156:14:156:21 | captured | provenance | | -| main.rs:153:24:153:34 | source(...) | main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | provenance | | +| main.rs:153:13:153:20 | captured | main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | provenance | | +| main.rs:153:24:153:34 | source(...) | main.rs:153:13:153:20 | captured | provenance | | nodes | main.rs:10:20:10:52 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | | main.rs:10:30:10:39 | source(...) | semmle.label | source(...) | @@ -73,6 +97,28 @@ nodes | main.rs:22:9:22:9 | a | semmle.label | a | | main.rs:22:13:22:22 | source(...) | semmle.label | source(...) | | main.rs:23:13:23:13 | a | semmle.label | a | +| main.rs:27:9:27:18 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] | +| main.rs:27:10:27:14 | mut x | semmle.label | mut x | +| main.rs:27:22:27:35 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:27:23:27:31 | source(...) | semmle.label | source(...) | +| main.rs:28:6:28:6 | x | semmle.label | x | +| main.rs:29:14:29:14 | x | semmle.label | x | +| main.rs:33:9:33:16 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] | +| main.rs:33:10:33:14 | ref x | semmle.label | ref x | +| main.rs:33:14:33:14 | x [&ref] | semmle.label | x [&ref] | +| main.rs:33:20:33:31 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:33:21:33:29 | source(...) | semmle.label | source(...) | +| main.rs:34:14:34:15 | * ... | semmle.label | * ... | +| main.rs:34:15:34:15 | x [&ref] | semmle.label | x [&ref] | +| main.rs:38:20:38:27 | ... | semmle.label | ... | +| main.rs:38:30:38:56 | if cond {...} else {...} | semmle.label | if cond {...} else {...} | +| main.rs:39:9:39:9 | a | semmle.label | a | +| main.rs:39:13:39:22 | source(...) | semmle.label | source(...) | +| main.rs:40:9:40:9 | b | semmle.label | b | +| main.rs:40:13:40:22 | f(...) | semmle.label | f(...) | +| main.rs:40:21:40:21 | a | semmle.label | a | +| main.rs:41:10:41:10 | b | semmle.label | b | +| main.rs:48:9:48:12 | capt | semmle.label | capt | | main.rs:48:16:48:25 | source(...) | semmle.label | source(...) | | main.rs:50:5:50:5 | [post] f : ... => .. [captured capt] | semmle.label | [post] f : ... => .. [captured capt] | | main.rs:51:10:51:13 | capt | semmle.label | capt | @@ -122,6 +168,7 @@ nodes | main.rs:112:17:112:17 | ... | semmle.label | ... | | main.rs:112:25:112:25 | x | semmle.label | x | | main.rs:112:29:112:29 | b | semmle.label | b | +| main.rs:120:9:120:9 | a | semmle.label | a | | main.rs:120:13:120:22 | source(...) | semmle.label | source(...) | | main.rs:121:26:121:36 | \|...\| ... : ... => .. [captured a] | semmle.label | \|...\| ... : ... => .. [captured a] | | main.rs:121:35:121:35 | a | semmle.label | a | @@ -133,23 +180,30 @@ nodes | main.rs:124:35:124:35 | a | semmle.label | a | | main.rs:131:30:131:40 | source(...) | semmle.label | source(...) | | main.rs:132:14:132:25 | await future | semmle.label | await future | +| main.rs:136:13:136:16 | data | semmle.label | data | | main.rs:136:20:136:30 | source(...) | semmle.label | source(...) | | main.rs:137:9:139:9 | { ... } : ... => .. [captured data] | semmle.label | { ... } : ... => .. [captured data] | | main.rs:138:18:138:21 | data | semmle.label | data | +| main.rs:144:13:144:16 | data | semmle.label | data | | main.rs:144:20:144:30 | source(...) | semmle.label | source(...) | | main.rs:145:30:145:33 | data | semmle.label | data | | main.rs:146:14:146:19 | future [captured data] | semmle.label | future [captured data] | | main.rs:146:14:146:25 | await future | semmle.label | await future | | main.rs:152:9:154:9 | [post] { ... } : ... => .. [captured captured] | semmle.label | [post] { ... } : ... => .. [captured captured] | +| main.rs:153:13:153:20 | captured | semmle.label | captured | | main.rs:153:24:153:34 | source(...) | semmle.label | source(...) | | main.rs:156:14:156:21 | captured | semmle.label | captured | subpaths +| main.rs:40:21:40:21 | a | main.rs:38:20:38:27 | ... | main.rs:38:30:38:56 | if cond {...} else {...} | main.rs:40:13:40:22 | f(...) | | main.rs:88:21:88:21 | a | main.rs:77:24:77:32 | ...: i64 | main.rs:77:42:83:1 | { ... } | main.rs:88:13:88:22 | f(...) | | main.rs:146:14:146:19 | future [captured data] | main.rs:145:30:145:33 | data | main.rs:145:30:145:33 | data | main.rs:146:14:146:25 | await future | testFailures #select | main.rs:11:10:11:16 | f(...) | main.rs:10:30:10:39 | source(...) | main.rs:11:10:11:16 | f(...) | $@ | main.rs:10:30:10:39 | source(...) | source(...) | | main.rs:17:18:17:21 | data | main.rs:22:13:22:22 | source(...) | main.rs:17:18:17:21 | data | $@ | main.rs:22:13:22:22 | source(...) | source(...) | +| main.rs:29:14:29:14 | x | main.rs:27:23:27:31 | source(...) | main.rs:29:14:29:14 | x | $@ | main.rs:27:23:27:31 | source(...) | source(...) | +| main.rs:34:14:34:15 | * ... | main.rs:33:21:33:29 | source(...) | main.rs:34:14:34:15 | * ... | $@ | main.rs:33:21:33:29 | source(...) | source(...) | +| main.rs:41:10:41:10 | b | main.rs:39:13:39:22 | source(...) | main.rs:41:10:41:10 | b | $@ | main.rs:39:13:39:22 | source(...) | source(...) | | main.rs:51:10:51:13 | capt | main.rs:48:16:48:25 | source(...) | main.rs:51:10:51:13 | capt | $@ | main.rs:48:16:48:25 | source(...) | source(...) | | main.rs:53:14:53:17 | capt | main.rs:48:16:48:25 | source(...) | main.rs:53:14:53:17 | capt | $@ | main.rs:48:16:48:25 | source(...) | source(...) | | main.rs:63:10:63:13 | data | main.rs:73:13:73:22 | source(...) | main.rs:63:10:63:13 | data | $@ | main.rs:73:13:73:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/lambdas/main.rs b/rust/ql/test/library-tests/dataflow/lambdas/main.rs index cbbadacb0b2f..004af9f9a993 100644 --- a/rust/ql/test/library-tests/dataflow/lambdas/main.rs +++ b/rust/ql/test/library-tests/dataflow/lambdas/main.rs @@ -26,19 +26,19 @@ fn closure_flow_in() { fn closure_flow_in2() { let (mut x, y) = (source(1), 0); (x) = x; - (|| sink(x))(); // $ MISSING: hasValueFlow=1 + (|| sink(x))(); // $ hasValueFlow=1 } fn closure_flow_in3() { let (ref x,) = (source(1),); - (|| sink(*x))(); // $ MISSING: hasValueFlow=1 + (|| sink(*x))(); // $ hasValueFlow=1 } fn closure_flow_through() { let f = |cond, ((data))| if cond { data } else { 0 }; let a = source(43); let b = f(true, a); - sink(b); // $ MISSING: hasValueFlow=43 + sink(b); // $ hasValueFlow=43 } fn closure_captured_variable() { diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index c6984639dcef..9c039d360fc5 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -672,8 +672,8 @@ localStep | main.rs:478:39:478:72 | ...: Vec::<...> | main.rs:478:39:478:43 | names | | main.rs:479:9:479:20 | default_name | main.rs:479:9:479:20 | [SSA] default_name | | main.rs:479:9:479:20 | default_name | main.rs:479:9:479:20 | default_name | +| main.rs:479:9:479:20 | default_name | main.rs:480:9:480:20 | SSA phi read(default_name) | | main.rs:479:24:479:45 | ... .to_string() | main.rs:479:9:479:20 | default_name | -| main.rs:479:24:479:45 | ... .to_string() | main.rs:480:9:480:20 | SSA phi read(default_name) | | main.rs:480:5:486:5 | for ... in ... { ... } | main.rs:478:75:487:1 | { ... } | | main.rs:480:9:480:20 | SSA phi read(default_name) | main.rs:482:41:482:67 | default_name | | main.rs:480:10:480:13 | [SSA] cond | main.rs:481:12:481:15 | cond | diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index 4bb38eb73ca3..084bc23457eb 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -191,8 +191,10 @@ edges | main.rs:204:14:204:14 | ... | main.rs:205:14:205:14 | n | provenance | | | main.rs:208:11:208:11 | s | main.rs:204:14:204:14 | ... | provenance | MaD:28 | | main.rs:208:11:208:11 | s | main.rs:204:14:204:14 | ... | provenance | MaD:28 | -| main.rs:212:13:212:22 | source(...) | main.rs:214:23:214:23 | f [captured s] | provenance | | -| main.rs:212:13:212:22 | source(...) | main.rs:214:23:214:23 | f [captured s] | provenance | | +| main.rs:212:9:212:9 | s | main.rs:214:23:214:23 | f [captured s] | provenance | | +| main.rs:212:9:212:9 | s | main.rs:214:23:214:23 | f [captured s] | provenance | | +| main.rs:212:13:212:22 | source(...) | main.rs:212:9:212:9 | s | provenance | | +| main.rs:212:13:212:22 | source(...) | main.rs:212:9:212:9 | s | provenance | | | main.rs:213:40:213:40 | s | main.rs:213:17:213:42 | if ... {...} else {...} | provenance | | | main.rs:213:40:213:40 | s | main.rs:213:17:213:42 | if ... {...} else {...} | provenance | | | main.rs:214:9:214:9 | t | main.rs:215:10:215:10 | t | provenance | | @@ -596,6 +598,8 @@ nodes | main.rs:205:14:205:14 | n | semmle.label | n | | main.rs:208:11:208:11 | s | semmle.label | s | | main.rs:208:11:208:11 | s | semmle.label | s | +| main.rs:212:9:212:9 | s | semmle.label | s | +| main.rs:212:9:212:9 | s | semmle.label | s | | main.rs:212:13:212:22 | source(...) | semmle.label | source(...) | | main.rs:212:13:212:22 | source(...) | semmle.label | source(...) | | main.rs:213:17:213:42 | if ... {...} else {...} | semmle.label | if ... {...} else {...} | diff --git a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected index f0a2a08450c4..225511e90839 100644 --- a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected +++ b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected @@ -15,40 +15,39 @@ | src/main.rs:173:8:173:11 | path | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:173:8:173:11 | path | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | | src/main.rs:174:36:174:43 | path_str | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:174:36:174:43 | path_str | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | | src/main.rs:177:36:177:39 | path | src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:177:36:177:39 | path | This path depends on a $@. | src/main.rs:211:17:211:32 | ...::args(...) | user-provided value | -| src/main.rs:192:73:192:84 | &... | src/main.rs:206:37:206:48 | destructured | src/main.rs:192:73:192:84 | &... | This path depends on a $@. | src/main.rs:206:37:206:48 | destructured | user-provided value | | src/main.rs:201:73:201:76 | path | src/main.rs:208:33:208:39 | request | src/main.rs:201:73:201:76 | path | This path depends on a $@. | src/main.rs:208:33:208:39 | request | user-provided value | edges | src/main.rs:7:11:7:19 | file_name | src/main.rs:9:35:9:43 | file_name | provenance | | | src/main.rs:9:9:9:17 | file_path | src/main.rs:11:24:11:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:9:21:9:44 | ...::from(...) | src/main.rs:9:9:9:17 | file_path | provenance | | -| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:17 | +| src/main.rs:9:35:9:43 | file_name | src/main.rs:9:21:9:44 | ...::from(...) | provenance | MaD:15 | | src/main.rs:38:11:38:19 | file_path | src/main.rs:41:52:41:60 | file_path | provenance | | | src/main.rs:41:9:41:17 | file_path | src/main.rs:46:24:46:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:41:21:41:62 | public_path.join(...) | src/main.rs:41:9:41:17 | file_path | provenance | | -| src/main.rs:41:38:41:61 | ...::from(...) | src/main.rs:41:21:41:62 | public_path.join(...) | provenance | MaD:15 | -| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:17 | +| src/main.rs:41:38:41:61 | ...::from(...) | src/main.rs:41:21:41:62 | public_path.join(...) | provenance | MaD:13 | +| src/main.rs:41:52:41:60 | file_path | src/main.rs:41:38:41:61 | ...::from(...) | provenance | MaD:15 | | src/main.rs:63:11:63:19 | file_path | src/main.rs:66:32:66:40 | file_path | provenance | | | src/main.rs:66:9:66:17 | file_path [&ref] | src/main.rs:71:24:71:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | src/main.rs:66:9:66:17 | file_path [&ref] | provenance | | -| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:16 | +| src/main.rs:66:31:66:40 | &file_path [&ref] | src/main.rs:66:21:66:41 | ...::new(...) [&ref] | provenance | MaD:14 | | src/main.rs:66:32:66:40 | file_path | src/main.rs:66:31:66:40 | &file_path [&ref] | provenance | | | src/main.rs:76:11:76:19 | file_path | src/main.rs:79:52:79:60 | file_path | provenance | | | src/main.rs:79:9:79:17 | file_path | src/main.rs:80:21:80:29 | file_path | provenance | | | src/main.rs:79:21:79:62 | public_path.join(...) | src/main.rs:79:9:79:17 | file_path | provenance | | -| src/main.rs:79:38:79:61 | ...::from(...) | src/main.rs:79:21:79:62 | public_path.join(...) | provenance | MaD:15 | -| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:17 | +| src/main.rs:79:38:79:61 | ...::from(...) | src/main.rs:79:21:79:62 | public_path.join(...) | provenance | MaD:13 | +| src/main.rs:79:52:79:60 | file_path | src/main.rs:79:38:79:61 | ...::from(...) | provenance | MaD:15 | | src/main.rs:80:9:80:17 | file_path | src/main.rs:85:24:85:32 | file_path | provenance | Sink:MaD:6 | -| src/main.rs:80:21:80:29 | file_path | src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | provenance | MaD:18 | -| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | src/main.rs:80:21:80:53 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:80:21:80:29 | file_path | src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | provenance | MaD:16 | +| src/main.rs:80:21:80:44 | file_path.canonicalize() [Ok] | src/main.rs:80:21:80:53 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:80:21:80:53 | ... .unwrap() | src/main.rs:80:9:80:17 | file_path | provenance | | | src/main.rs:90:11:90:19 | file_path | src/main.rs:93:32:93:40 | file_path | provenance | | | src/main.rs:93:9:93:17 | file_path [&ref] | src/main.rs:98:21:98:29 | file_path [&ref] | provenance | | | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | src/main.rs:93:9:93:17 | file_path [&ref] | provenance | | -| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:16 | +| src/main.rs:93:31:93:40 | &file_path [&ref] | src/main.rs:93:21:93:41 | ...::new(...) [&ref] | provenance | MaD:14 | | src/main.rs:93:32:93:40 | file_path | src/main.rs:93:31:93:40 | &file_path [&ref] | provenance | | | src/main.rs:98:9:98:17 | file_path | src/main.rs:99:24:99:32 | file_path | provenance | Sink:MaD:6 | | src/main.rs:98:21:98:29 | file_path [&ref] | src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | provenance | Config | -| src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | src/main.rs:98:21:98:53 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:98:21:98:44 | file_path.canonicalize() [Ok] | src/main.rs:98:21:98:53 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:98:21:98:53 | ... .unwrap() | src/main.rs:98:9:98:17 | file_path | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:104:33:104:37 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:106:39:106:43 | path1 | provenance | | @@ -57,62 +56,56 @@ edges | src/main.rs:103:9:103:13 | path1 | src/main.rs:115:39:115:43 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:122:27:122:31 | path1 | provenance | | | src/main.rs:103:9:103:13 | path1 | src/main.rs:123:37:123:41 | path1 | provenance | | -| src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:9 | -| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:11 | -| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:13 | +| src/main.rs:103:17:103:32 | ...::args(...) | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:8 | +| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:10 | +| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:11 | | src/main.rs:103:17:103:48 | ... .unwrap() | src/main.rs:103:9:103:13 | path1 | provenance | | -| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:10 | +| src/main.rs:104:33:104:37 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:9 | | src/main.rs:104:33:104:45 | path1.clone() | src/main.rs:104:33:104:45 | path1.clone() | provenance | Sink:MaD:2 | | src/main.rs:106:9:106:13 | path2 | src/main.rs:107:33:107:37 | path2 | provenance | Sink:MaD:2 | -| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | src/main.rs:106:17:106:61 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:106:17:106:61 | ... .unwrap() | src/main.rs:106:9:106:13 | path2 | provenance | | -| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:10 | +| src/main.rs:106:39:106:43 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:9 | | src/main.rs:106:39:106:51 | path1.clone() | src/main.rs:106:17:106:52 | ...::canonicalize(...) [Ok] | provenance | Config | | src/main.rs:109:9:109:13 | path3 | src/main.rs:110:35:110:39 | path3 | provenance | Sink:MaD:4 | | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | src/main.rs:109:17:109:60 | await ... [Ok] | provenance | | -| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:109:17:109:60 | await ... [Ok] | src/main.rs:109:17:109:69 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:109:17:109:69 | ... .unwrap() | src/main.rs:109:9:109:13 | path3 | provenance | | -| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:10 | +| src/main.rs:109:41:109:45 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:9 | | src/main.rs:109:41:109:53 | path1.clone() | src/main.rs:109:17:109:54 | ...::canonicalize(...) [future, Ok] | provenance | Config | | src/main.rs:112:9:112:13 | path4 | src/main.rs:113:39:113:43 | path4 | provenance | Sink:MaD:1 | | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | src/main.rs:112:17:112:64 | await ... [Ok] | provenance | | -| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:112:17:112:64 | await ... [Ok] | src/main.rs:112:17:112:73 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:112:17:112:73 | ... .unwrap() | src/main.rs:112:9:112:13 | path4 | provenance | | -| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:10 | +| src/main.rs:112:45:112:49 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:9 | | src/main.rs:112:45:112:57 | path1.clone() | src/main.rs:112:17:112:58 | ...::canonicalize(...) [future, Ok] | provenance | Config | | src/main.rs:115:9:115:13 | path5 [&ref] | src/main.rs:116:33:116:37 | path5 | provenance | Sink:MaD:2 | | src/main.rs:115:9:115:13 | path5 [&ref] | src/main.rs:118:17:118:21 | path5 [&ref] | provenance | | | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | src/main.rs:115:9:115:13 | path5 [&ref] | provenance | | -| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:16 | +| src/main.rs:115:38:115:43 | &path1 [&ref] | src/main.rs:115:17:115:44 | ...::new(...) [&ref] | provenance | MaD:14 | | src/main.rs:115:39:115:43 | path1 | src/main.rs:115:38:115:43 | &path1 [&ref] | provenance | | | src/main.rs:118:9:118:13 | path6 | src/main.rs:119:33:119:37 | path6 | provenance | Sink:MaD:2 | | src/main.rs:118:17:118:21 | path5 [&ref] | src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | provenance | Config | -| src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | src/main.rs:118:17:118:45 | ... .unwrap() | provenance | MaD:14 | +| src/main.rs:118:17:118:36 | path5.canonicalize() [Ok] | src/main.rs:118:17:118:45 | ... .unwrap() | provenance | MaD:12 | | src/main.rs:118:17:118:45 | ... .unwrap() | src/main.rs:118:9:118:13 | path6 | provenance | | -| src/main.rs:122:27:122:31 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:10 | +| src/main.rs:122:27:122:31 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:9 | | src/main.rs:122:27:122:39 | path1.clone() | src/main.rs:122:27:122:39 | path1.clone() | provenance | Sink:MaD:5 | -| src/main.rs:123:37:123:41 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:10 | +| src/main.rs:123:37:123:41 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:9 | | src/main.rs:123:37:123:49 | path1.clone() | src/main.rs:123:37:123:49 | path1.clone() | provenance | Sink:MaD:5 | | src/main.rs:170:16:170:29 | ...: ... [&ref] | src/main.rs:172:26:172:33 | path_str [&ref] | provenance | | | src/main.rs:170:16:170:29 | ...: ... [&ref] | src/main.rs:174:36:174:43 | path_str | provenance | Sink:MaD:2 | | src/main.rs:172:9:172:12 | path [&ref] | src/main.rs:173:8:173:11 | path | provenance | Sink:MaD:3 | | src/main.rs:172:9:172:12 | path [&ref] | src/main.rs:177:36:177:39 | path | provenance | Sink:MaD:2 | | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | src/main.rs:172:9:172:12 | path [&ref] | provenance | | -| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:16 | -| src/main.rs:191:23:191:55 | ...: State::<...> | src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | provenance | | -| src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | src/main.rs:192:74:192:79 | config | provenance | heuristic-callback | -| src/main.rs:192:73:192:84 | &... [&ref] | src/main.rs:192:73:192:84 | &... | provenance | Sink:MaD:6 | -| src/main.rs:192:74:192:79 | config | src/main.rs:192:74:192:84 | config.path | provenance | MaD:12 | -| src/main.rs:192:74:192:84 | config.path | src/main.rs:192:73:192:84 | &... [&ref] | provenance | | +| src/main.rs:172:26:172:33 | path_str [&ref] | src/main.rs:172:16:172:34 | ...::new(...) [&ref] | provenance | MaD:14 | | src/main.rs:200:18:200:41 | ...: Json::<...> | src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | provenance | | | src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | src/main.rs:201:73:201:76 | path | provenance | heuristic-callback | | src/main.rs:201:73:201:76 | path | src/main.rs:201:73:201:76 | path | provenance | Sink:MaD:6 | -| src/main.rs:206:37:206:48 | destructured | src/main.rs:191:23:191:55 | ...: State::<...> | provenance | Src:MaD:7 | -| src/main.rs:208:33:208:39 | request | src/main.rs:200:18:200:41 | ...: Json::<...> | provenance | Src:MaD:8 | +| src/main.rs:208:33:208:39 | request | src/main.rs:200:18:200:41 | ...: Json::<...> | provenance | Src:MaD:7 | | src/main.rs:211:9:211:13 | path1 | src/main.rs:212:18:212:22 | path1 | provenance | | -| src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:211:17:211:32 | ...::args(...) [element] | provenance | Src:MaD:9 | -| src/main.rs:211:17:211:32 | ...::args(...) [element] | src/main.rs:211:17:211:39 | ... .nth(...) [Some] | provenance | MaD:11 | -| src/main.rs:211:17:211:39 | ... .nth(...) [Some] | src/main.rs:211:17:211:48 | ... .unwrap() | provenance | MaD:13 | +| src/main.rs:211:17:211:32 | ...::args(...) | src/main.rs:211:17:211:32 | ...::args(...) [element] | provenance | Src:MaD:8 | +| src/main.rs:211:17:211:32 | ...::args(...) [element] | src/main.rs:211:17:211:39 | ... .nth(...) [Some] | provenance | MaD:10 | +| src/main.rs:211:17:211:39 | ... .nth(...) [Some] | src/main.rs:211:17:211:48 | ... .unwrap() | provenance | MaD:11 | | src/main.rs:211:17:211:48 | ... .unwrap() | src/main.rs:211:9:211:13 | path1 | provenance | | | src/main.rs:212:17:212:22 | &path1 [&ref] | src/main.rs:170:16:170:29 | ...: ... [&ref] | provenance | | | src/main.rs:212:18:212:22 | path1 | src/main.rs:212:17:212:22 | &path1 [&ref] | provenance | | @@ -123,18 +116,16 @@ models | 4 | Sink: ::open; Argument[0]; path-injection | | 5 | Sink: std::fs::copy; Argument[0,1]; path-injection | | 6 | Sink: std::fs::read_to_string; Argument[0]; path-injection | -| 7 | Source: axum::routing::method_routing::get; Argument[0].Parameter[0..7]; remote | -| 8 | Source: axum::routing::method_routing::post; Argument[0].Parameter[0..7]; remote | -| 9 | Source: std::env::args; ReturnValue.Element; commandargs | -| 10 | Summary: ::clone; Argument[self].Reference; ReturnValue; value | -| 11 | Summary: ::nth; Argument[self].Reference.Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 12 | Summary: ::deref; Argument[self].Reference; ReturnValue.Reference; taint | -| 13 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 14 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 15 | Summary: ::join; Argument[0]; ReturnValue; taint | -| 16 | Summary: ::new; Argument[0].Reference; ReturnValue.Reference; value | -| 17 | Summary: ::from; Argument[0].Field[alloc::borrow::Cow::Owned(0)]; ReturnValue; value | -| 18 | Summary: ::deref; Argument[self].Reference.Field[std::path::PathBuf::inner]; ReturnValue.Reference; value | +| 7 | Source: axum::routing::method_routing::post; Argument[0].Parameter[0..7]; remote | +| 8 | Source: std::env::args; ReturnValue.Element; commandargs | +| 9 | Summary: ::clone; Argument[self].Reference; ReturnValue; value | +| 10 | Summary: ::nth; Argument[self].Reference.Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 11 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 12 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 13 | Summary: ::join; Argument[0]; ReturnValue; taint | +| 14 | Summary: ::new; Argument[0].Reference; ReturnValue.Reference; value | +| 15 | Summary: ::from; Argument[0].Field[alloc::borrow::Cow::Owned(0)]; ReturnValue; value | +| 16 | Summary: ::deref; Argument[self].Reference.Field[std::path::PathBuf::inner]; ReturnValue.Reference; value | nodes | src/main.rs:7:11:7:19 | file_name | semmle.label | file_name | | src/main.rs:9:9:9:17 | file_path | semmle.label | file_path | @@ -224,17 +215,10 @@ nodes | src/main.rs:173:8:173:11 | path | semmle.label | path | | src/main.rs:174:36:174:43 | path_str | semmle.label | path_str | | src/main.rs:177:36:177:39 | path | semmle.label | path | -| src/main.rs:191:23:191:55 | ...: State::<...> | semmle.label | ...: State::<...> | -| src/main.rs:192:41:192:85 | \|...\| ... : ... => .. [captured config] | semmle.label | \|...\| ... : ... => .. [captured config] | -| src/main.rs:192:73:192:84 | &... | semmle.label | &... | -| src/main.rs:192:73:192:84 | &... [&ref] | semmle.label | &... [&ref] | -| src/main.rs:192:74:192:79 | config | semmle.label | config | -| src/main.rs:192:74:192:84 | config.path | semmle.label | config.path | | src/main.rs:200:18:200:41 | ...: Json::<...> | semmle.label | ...: Json::<...> | | src/main.rs:201:41:201:77 | \|...\| ... : ... => .. [captured path] | semmle.label | \|...\| ... : ... => .. [captured path] | | src/main.rs:201:73:201:76 | path | semmle.label | path | | src/main.rs:201:73:201:76 | path | semmle.label | path | -| src/main.rs:206:37:206:48 | destructured | semmle.label | destructured | | src/main.rs:208:33:208:39 | request | semmle.label | request | | src/main.rs:211:9:211:13 | path1 | semmle.label | path1 | | src/main.rs:211:17:211:32 | ...::args(...) | semmle.label | ...::args(...) | diff --git a/rust/ql/test/query-tests/security/CWE-022/src/main.rs b/rust/ql/test/query-tests/security/CWE-022/src/main.rs index bdc33b4d3764..5f1a11c40d55 100644 --- a/rust/ql/test/query-tests/security/CWE-022/src/main.rs +++ b/rust/ql/test/query-tests/security/CWE-022/src/main.rs @@ -189,7 +189,7 @@ struct Config { } async fn destructured(State(config): State>) { - let _ = tokio::task::spawn_blocking(move || std::fs::read_to_string(&config.path)).await; // $ path-injection-sink $ SPURIOUS: Alert[rust/path-injection]=s1 + let _ = tokio::task::spawn_blocking(move || std::fs::read_to_string(&config.path)).await; // $ path-injection-sink } async fn local_clone(state: State>) { @@ -203,7 +203,7 @@ async fn request(Json(path): Json) { fn main() { let _: Router = Router::new() - .route("/destructured", get(destructured)) // $ SPURIOUS: Source=s1 + .route("/destructured", get(destructured)) .route("/local-clone", get(local_clone)) .route("/request", post(request)) // $ Source=s3 .with_state(Arc::new(Config { path: String::from("configured-file") }));