From 9583a2a7d32c6a1175e748d5045d0385911cb968 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:57:33 +0000 Subject: [PATCH 1/7] Rust: Additional test cases for reqwest sources. --- .../dataflow/sources/TaintSources.expected | 6 +++++- .../test/library-tests/dataflow/sources/test.rs | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected index e127b06cce96..02acbd5bbeb4 100644 --- a/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected +++ b/rust/ql/test/library-tests/dataflow/sources/TaintSources.expected @@ -14,4 +14,8 @@ | test.rs:52:16:52:33 | ...::home_dir | Flow source 'CommandLineArgs' of type commandargs. | | test.rs:60:26:60:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | | test.rs:63:26:63:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | -| test.rs:66:26:66:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:66:26:66:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:69:26:69:47 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:72:26:72:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:75:26:75:37 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | +| test.rs:78:24:78:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index de482c251065..90df4fac0460 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -63,8 +63,22 @@ async fn test_reqwest() -> Result<(), reqwest::Error> { let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources] sink(remote_string2); // $ MISSING: hasTaintFlow - let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources] + let remote_string3 = reqwest::blocking::get("http://example.com/").unwrap().text_with_charset("utf-8").unwrap(); // $ Alert[rust/summary/taint-sources] sink(remote_string3); // $ MISSING: hasTaintFlow + let remote_string4 = reqwest::blocking::get("http://example.com/").unwrap().bytes().unwrap(); // $ Alert[rust/summary/taint-sources] + sink(remote_string4); // $ MISSING: hasTaintFlow + + let remote_string5 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources] + sink(remote_string5); // $ MISSING: hasTaintFlow + + let remote_string6 = reqwest::get("http://example.com/").await?.bytes().await?; // $ Alert[rust/summary/taint-sources] + sink(remote_string6); // $ MISSING: hasTaintFlow + + let mut request1 = reqwest::get("http://example.com/").await?; // $ Alert[rust/summary/taint-sources] + while let Some(chunk) = request1.chunk().await? { + sink(chunk); // $ MISSING: hasTaintFlow + } + Ok(()) } From 23ac35e5ca93daed8a433d09567de01f66990400 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:24:06 +0000 Subject: [PATCH 2/7] Rust: Model more Reqwest methods (.await still doesn't work though). --- .../lib/codeql/rust/frameworks/reqwest.model.yml | 10 ++++++++-- .../dataflow/local/DataFlowStep.expected | 5 +++++ .../dataflow/sources/InlineFlow.expected | 4 ++++ .../dataflow/taint/TaintFlowStep.expected | 14 ++++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml index 6e05730169ed..4244c4cfaa19 100644 --- a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml @@ -3,10 +3,16 @@ extensions: pack: codeql/rust-all extensible: sourceModel data: - - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::get", "ReturnValue", "remote", "manual"] - - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::blocking::get", "ReturnValue", "remote", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::get", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "remote", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "crate::blocking::get", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "remote", "manual"] - addsTo: pack: codeql/rust-all extensible: summaryModel data: + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text_with_charset", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::bytes", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::chunk", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text_with_charset", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::bytes", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 3ed8937fd81c..451b5a9b6503 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -478,7 +478,12 @@ models | 7 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value | | 8 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | storeStep +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | | main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr | | main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr | | main.rs:100:14:100:14 | 2 | tuple.0 | main.rs:100:13:100:30 | TupleExpr | diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected index e69de29bb2d1..08498d195947 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected @@ -0,0 +1,4 @@ +| test.rs:61:10:61:23 | remote_string1 | Unexpected result: hasTaintFlow="http://example.com/" | +| test.rs:64:10:64:23 | remote_string2 | Unexpected result: hasTaintFlow="http://example.com/" | +| test.rs:67:10:67:23 | remote_string3 | Unexpected result: hasTaintFlow="http://example.com/" | +| test.rs:70:10:70:23 | remote_string4 | Unexpected result: hasTaintFlow="http://example.com/" | diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected index 4ca0f8199314..17f60b60aaf1 100644 --- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected @@ -2,7 +2,12 @@ additionalTaintStep | file://:0:0:0:0 | [summary param] 0 in lang:alloc::_::crate::fmt::format | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::crate::fmt::format | MaD:3 | | file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_bytes | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_bytes | MaD:1 | | file://:0:0:0:0 | [summary param] self in lang:alloc::_::::as_str | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::::as_str | MaD:2 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:4 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:4 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:5 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:6 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:7 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:8 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:9 | | main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | | | main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | | | main.rs:8:20:8:20 | s | main.rs:8:14:8:20 | FormatArgsExpr | | @@ -23,4 +28,9 @@ models | 1 | Summary: lang:alloc; ::as_bytes; Argument[self]; ReturnValue; taint | | 2 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint | | 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint | -| 4 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 4 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 5 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 6 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 9 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | From 7cf872baad8707350a6b586eedf895970494e9a6 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:00:08 +0000 Subject: [PATCH 3/7] Rust: Adjust the tests to work around test processing of /. --- .../dataflow/sources/InlineFlow.expected | 4 ---- .../library-tests/dataflow/sources/test.rs | 22 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected index 08498d195947..e69de29bb2d1 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected @@ -1,4 +0,0 @@ -| test.rs:61:10:61:23 | remote_string1 | Unexpected result: hasTaintFlow="http://example.com/" | -| test.rs:64:10:64:23 | remote_string2 | Unexpected result: hasTaintFlow="http://example.com/" | -| test.rs:67:10:67:23 | remote_string3 | Unexpected result: hasTaintFlow="http://example.com/" | -| test.rs:70:10:70:23 | remote_string4 | Unexpected result: hasTaintFlow="http://example.com/" | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 90df4fac0460..0143ccac36c2 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -57,25 +57,25 @@ fn test_env_dirs() { } async fn test_reqwest() -> Result<(), reqwest::Error> { - let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ Alert[rust/summary/taint-sources] - sink(remote_string1); // $ MISSING: hasTaintFlow + let remote_string1 = reqwest::blocking::get("example.com")?.text()?; // $ Alert[rust/summary/taint-sources] + sink(remote_string1); // $ hasTaintFlow="example.com" - let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources] - sink(remote_string2); // $ MISSING: hasTaintFlow + let remote_string2 = reqwest::blocking::get("example.com").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources] + sink(remote_string2); // $ hasTaintFlow="example.com" - let remote_string3 = reqwest::blocking::get("http://example.com/").unwrap().text_with_charset("utf-8").unwrap(); // $ Alert[rust/summary/taint-sources] - sink(remote_string3); // $ MISSING: hasTaintFlow + let remote_string3 = reqwest::blocking::get("example.com").unwrap().text_with_charset("utf-8").unwrap(); // $ Alert[rust/summary/taint-sources] + sink(remote_string3); // $ hasTaintFlow="example.com" - let remote_string4 = reqwest::blocking::get("http://example.com/").unwrap().bytes().unwrap(); // $ Alert[rust/summary/taint-sources] - sink(remote_string4); // $ MISSING: hasTaintFlow + let remote_string4 = reqwest::blocking::get("example.com").unwrap().bytes().unwrap(); // $ Alert[rust/summary/taint-sources] + sink(remote_string4); // $ hasTaintFlow="example.com" - let remote_string5 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources] + let remote_string5 = reqwest::get("example.com").await?.text().await?; // $ Alert[rust/summary/taint-sources] sink(remote_string5); // $ MISSING: hasTaintFlow - let remote_string6 = reqwest::get("http://example.com/").await?.bytes().await?; // $ Alert[rust/summary/taint-sources] + let remote_string6 = reqwest::get("example.com").await?.bytes().await?; // $ Alert[rust/summary/taint-sources] sink(remote_string6); // $ MISSING: hasTaintFlow - let mut request1 = reqwest::get("http://example.com/").await?; // $ Alert[rust/summary/taint-sources] + let mut request1 = reqwest::get("example.com").await?; // $ Alert[rust/summary/taint-sources] while let Some(chunk) = request1.chunk().await? { sink(chunk); // $ MISSING: hasTaintFlow } From 9ea9f3ae19408bba7ea3b9a99f2c8f99d82a8d62 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:09:21 +0000 Subject: [PATCH 4/7] Update rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml index 4244c4cfaa19..ef0b947a3ad8 100644 --- a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml @@ -12,7 +12,7 @@ extensions: - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text_with_charset", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::bytes", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] - - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::chunk", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)", "taint", "manual"] + - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::chunk", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)]", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::text_with_charset", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] - ["repo:https://github.com/seanmonstar/reqwest:reqwest", "::bytes", "Argument[self]", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "taint", "manual"] From 9d6a13cec26a44e9bf3afacfc832e1603c61d095 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 21:58:09 +0000 Subject: [PATCH 5/7] Rust: Accept improved results for `rust/sql-injection`. Note that the lost annotations are only sources, not results, and I suspect will return when we have sufficient flow in these cases. --- .../security/CWE-089/SqlInjection.expected | 41 +++++++++++++++++++ .../test/query-tests/security/CWE-089/sqlx.rs | 8 ++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index 58f42bec0c84..c106f22e7ca7 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -1,4 +1,45 @@ #select +| sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | edges +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:56:34:56:89 | MacroExpr | provenance | | +| sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 | +| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap(...) | provenance | MaD:4 | +| sqlx.rs:48:25:48:78 | ... .unwrap(...) | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | provenance | MaD:7 | +| sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:5 | +| sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | sqlx.rs:48:9:48:21 | remote_string | provenance | | +| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:67:30:67:43 | unsafe_query_4 | provenance | | +| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:78:29:78:42 | unsafe_query_4 | provenance | | +| sqlx.rs:56:26:56:90 | res | sqlx.rs:56:34:56:89 | { ... } | provenance | | +| sqlx.rs:56:34:56:89 | ...::format(...) | sqlx.rs:56:26:56:90 | res | provenance | | +| sqlx.rs:56:34:56:89 | ...::must_use(...) | sqlx.rs:56:9:56:22 | unsafe_query_4 | provenance | | +| sqlx.rs:56:34:56:89 | MacroExpr | sqlx.rs:56:34:56:89 | ...::format(...) | provenance | MaD:3 | +| sqlx.rs:56:34:56:89 | { ... } | sqlx.rs:56:34:56:89 | ...::must_use(...) | provenance | MaD:6 | +| sqlx.rs:67:30:67:43 | unsafe_query_4 | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | provenance | MaD:2 | +| sqlx.rs:78:29:78:42 | unsafe_query_4 | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | provenance | MaD:2 | +models +| 1 | Source: repo:https://github.com/seanmonstar/reqwest:reqwest; crate::blocking::get; remote; ReturnValue.Variant[crate::result::Result::Ok(0)] | +| 2 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint | +| 3 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint | +| 4 | Summary: lang:core; ::unwrap; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value | +| 5 | Summary: lang:core; ::unwrap_or; Argument[self].Variant[crate::result::Result::Ok(0)]; ReturnValue; value | +| 6 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value | +| 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | nodes +| sqlx.rs:48:9:48:21 | remote_string | semmle.label | remote_string | +| sqlx.rs:48:25:48:46 | ...::get | semmle.label | ...::get | +| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] | +| sqlx.rs:48:25:48:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | +| sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] | +| sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:56:9:56:22 | unsafe_query_4 | semmle.label | unsafe_query_4 | +| sqlx.rs:56:26:56:90 | res | semmle.label | res | +| sqlx.rs:56:34:56:89 | ...::format(...) | semmle.label | ...::format(...) | +| sqlx.rs:56:34:56:89 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| sqlx.rs:56:34:56:89 | MacroExpr | semmle.label | MacroExpr | +| sqlx.rs:56:34:56:89 | { ... } | semmle.label | { ... } | +| sqlx.rs:67:30:67:43 | unsafe_query_4 | semmle.label | unsafe_query_4 | +| sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | +| sqlx.rs:78:29:78:42 | unsafe_query_4 | semmle.label | unsafe_query_4 | +| sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index 257e1b6004d4..24d3e585e95b 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -64,7 +64,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err if enable_remote { let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 - let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 + let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 } // prepared queries @@ -75,7 +75,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err if enable_remote { let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 } let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(arg_string).execute(&pool).await?; // $ sql-sink @@ -93,7 +93,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote2 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote2 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) @@ -166,7 +166,7 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote3 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote3 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) From 494d8f2da0631bf342babbd012e8ab978fc050bd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:12:53 +0000 Subject: [PATCH 6/7] Rust: Update MaD IDs for an unrelated test. :( --- .../CWE-312/CleartextLogging.expected | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected index e4feee0fd55d..0cca29f32b3f 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected @@ -136,8 +136,8 @@ edges | test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | | | test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:46 | res | provenance | | | test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | | -| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | | | test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:19 | ...::log | provenance | MaD:0 Sink:MaD:0 | | test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:42 | ...::log | provenance | MaD:0 Sink:MaD:0 | @@ -180,45 +180,45 @@ edges | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | test_logging.rs:167:17:167:64 | ...::assert_failed | provenance | MaD:10 Sink:MaD:10 | | test_logging.rs:167:40:167:63 | MacroExpr | test_logging.rs:167:40:167:63 | ...::Some(...) [Some] | provenance | | | test_logging.rs:167:56:167:63 | password | test_logging.rs:167:40:167:63 | MacroExpr | provenance | | -| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:45 | +| test_logging.rs:168:34:168:66 | MacroExpr | test_logging.rs:168:34:168:75 | ... .as_str(...) | provenance | MaD:51 | | test_logging.rs:168:34:168:66 | res | test_logging.rs:168:42:168:65 | { ... } | provenance | | | test_logging.rs:168:34:168:75 | ... .as_str(...) | test_logging.rs:168:27:168:32 | expect | provenance | MaD:11 Sink:MaD:11 | | test_logging.rs:168:42:168:65 | ...::format(...) | test_logging.rs:168:34:168:66 | res | provenance | | | test_logging.rs:168:42:168:65 | ...::must_use(...) | test_logging.rs:168:34:168:66 | MacroExpr | provenance | | -| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:168:42:168:65 | MacroExpr | test_logging.rs:168:42:168:65 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:168:42:168:65 | { ... } | test_logging.rs:168:42:168:65 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:168:58:168:65 | password | test_logging.rs:168:42:168:65 | MacroExpr | provenance | | -| test_logging.rs:174:36:174:70 | MacroExpr | test_logging.rs:174:36:174:81 | ... .as_bytes(...) | provenance | MaD:46 | +| test_logging.rs:174:36:174:70 | MacroExpr | test_logging.rs:174:36:174:81 | ... .as_bytes(...) | provenance | MaD:52 | | test_logging.rs:174:36:174:70 | res | test_logging.rs:174:44:174:69 | { ... } | provenance | | | test_logging.rs:174:36:174:81 | ... .as_bytes(...) | test_logging.rs:174:30:174:34 | write | provenance | MaD:5 Sink:MaD:5 | | test_logging.rs:174:44:174:69 | ...::format(...) | test_logging.rs:174:36:174:70 | res | provenance | | | test_logging.rs:174:44:174:69 | ...::must_use(...) | test_logging.rs:174:36:174:70 | MacroExpr | provenance | | -| test_logging.rs:174:44:174:69 | MacroExpr | test_logging.rs:174:44:174:69 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:174:44:174:69 | { ... } | test_logging.rs:174:44:174:69 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:174:44:174:69 | MacroExpr | test_logging.rs:174:44:174:69 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:174:44:174:69 | { ... } | test_logging.rs:174:44:174:69 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:174:62:174:69 | password | test_logging.rs:174:44:174:69 | MacroExpr | provenance | | -| test_logging.rs:175:40:175:74 | MacroExpr | test_logging.rs:175:40:175:85 | ... .as_bytes(...) | provenance | MaD:46 | +| test_logging.rs:175:40:175:74 | MacroExpr | test_logging.rs:175:40:175:85 | ... .as_bytes(...) | provenance | MaD:52 | | test_logging.rs:175:40:175:74 | res | test_logging.rs:175:48:175:73 | { ... } | provenance | | | test_logging.rs:175:40:175:85 | ... .as_bytes(...) | test_logging.rs:175:30:175:38 | write_all | provenance | MaD:6 Sink:MaD:6 | | test_logging.rs:175:48:175:73 | ...::format(...) | test_logging.rs:175:40:175:74 | res | provenance | | | test_logging.rs:175:48:175:73 | ...::must_use(...) | test_logging.rs:175:40:175:74 | MacroExpr | provenance | | -| test_logging.rs:175:48:175:73 | MacroExpr | test_logging.rs:175:48:175:73 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:175:48:175:73 | { ... } | test_logging.rs:175:48:175:73 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:175:48:175:73 | MacroExpr | test_logging.rs:175:48:175:73 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:175:48:175:73 | { ... } | test_logging.rs:175:48:175:73 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:175:66:175:73 | password | test_logging.rs:175:48:175:73 | MacroExpr | provenance | | -| test_logging.rs:178:15:178:49 | MacroExpr | test_logging.rs:178:15:178:60 | ... .as_bytes(...) | provenance | MaD:46 | +| test_logging.rs:178:15:178:49 | MacroExpr | test_logging.rs:178:15:178:60 | ... .as_bytes(...) | provenance | MaD:52 | | test_logging.rs:178:15:178:49 | res | test_logging.rs:178:23:178:48 | { ... } | provenance | | | test_logging.rs:178:15:178:60 | ... .as_bytes(...) | test_logging.rs:178:9:178:13 | write | provenance | MaD:5 Sink:MaD:5 | | test_logging.rs:178:23:178:48 | ...::format(...) | test_logging.rs:178:15:178:49 | res | provenance | | | test_logging.rs:178:23:178:48 | ...::must_use(...) | test_logging.rs:178:15:178:49 | MacroExpr | provenance | | -| test_logging.rs:178:23:178:48 | MacroExpr | test_logging.rs:178:23:178:48 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:178:23:178:48 | { ... } | test_logging.rs:178:23:178:48 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:178:23:178:48 | MacroExpr | test_logging.rs:178:23:178:48 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:178:23:178:48 | { ... } | test_logging.rs:178:23:178:48 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:178:41:178:48 | password | test_logging.rs:178:23:178:48 | MacroExpr | provenance | | -| test_logging.rs:181:15:181:49 | MacroExpr | test_logging.rs:181:15:181:60 | ... .as_bytes(...) | provenance | MaD:46 | +| test_logging.rs:181:15:181:49 | MacroExpr | test_logging.rs:181:15:181:60 | ... .as_bytes(...) | provenance | MaD:52 | | test_logging.rs:181:15:181:49 | res | test_logging.rs:181:23:181:48 | { ... } | provenance | | | test_logging.rs:181:15:181:60 | ... .as_bytes(...) | test_logging.rs:181:9:181:13 | write | provenance | MaD:7 Sink:MaD:7 | | test_logging.rs:181:23:181:48 | ...::format(...) | test_logging.rs:181:15:181:49 | res | provenance | | | test_logging.rs:181:23:181:48 | ...::must_use(...) | test_logging.rs:181:15:181:49 | MacroExpr | provenance | | -| test_logging.rs:181:23:181:48 | MacroExpr | test_logging.rs:181:23:181:48 | ...::format(...) | provenance | MaD:48 | -| test_logging.rs:181:23:181:48 | { ... } | test_logging.rs:181:23:181:48 | ...::must_use(...) | provenance | MaD:47 | +| test_logging.rs:181:23:181:48 | MacroExpr | test_logging.rs:181:23:181:48 | ...::format(...) | provenance | MaD:54 | +| test_logging.rs:181:23:181:48 | { ... } | test_logging.rs:181:23:181:48 | ...::must_use(...) | provenance | MaD:53 | | test_logging.rs:181:41:181:48 | password | test_logging.rs:181:23:181:48 | MacroExpr | provenance | | nodes | test_logging.rs:42:5:42:36 | ...::log | semmle.label | ...::log | From fd9fb10bb9c8d2a6ca9bf05a5d102f1b8d114770 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:50:09 +0000 Subject: [PATCH 7/7] Rust: Accept changes from fixing the ]. --- .../library-tests/dataflow/local/DataFlowStep.expected | 2 ++ .../dataflow/taint/TaintFlowStep.expected | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 451b5a9b6503..3633e6fd6154 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -482,8 +482,10 @@ storeStep | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | +| file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | Some | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | | main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr | | main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr | | main.rs:100:14:100:14 | 2 | tuple.0 | main.rs:100:13:100:30 | TupleExpr | diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected index 17f60b60aaf1..8340a98d5941 100644 --- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected @@ -6,8 +6,9 @@ additionalTaintStep | file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:5 | | file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:6 | | file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::bytes | MaD:7 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:8 | -| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:9 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::chunk | MaD:8 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text | MaD:9 | +| file://:0:0:0:0 | [summary param] self in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | file://:0:0:0:0 | [summary] to write: ReturnValue.Variant[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::::text_with_charset | MaD:10 | | main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | | | main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | | | main.rs:8:20:8:20 | s | main.rs:8:14:8:20 | FormatArgsExpr | | @@ -32,5 +33,6 @@ models | 5 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | | 6 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | | 7 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::bytes; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | -| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | -| 9 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 8 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::chunk; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)].Variant[crate::option::Option::Some(0)]; taint | +| 9 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint | +| 10 | Summary: repo:https://github.com/seanmonstar/reqwest:reqwest; ::text_with_charset; Argument[self]; ReturnValue.Variant[crate::result::Result::Ok(0)]; taint |