Skip to content

Commit 652d32d

Browse files
authored
Merge pull request #19626 from geoffw0/futures
Rust: Model futures-io, rustls, futures-rustls
2 parents dc81f5a + fd2154d commit 652d32d

File tree

10 files changed

+294
-37
lines changed

10 files changed

+294
-37
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/rust-all
4+
extensible: sourceModel
5+
data:
6+
- ["repo:https://github.com/async-rs/async-std:async-std", "<crate::net::tcp::stream::TcpStream>::connect", "ReturnValue.Future.Field[crate::result::Result::Ok(0)]", "remote", "manual"]

rust/ql/lib/codeql/rust/frameworks/futures.model.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,16 @@ extensions:
44
extensible: summaryModel
55
data:
66
- ["repo:https://github.com/rust-lang/futures-rs:futures-executor", "crate::local_pool::block_on", "Argument[0]", "ReturnValue", "value", "manual"]
7+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "<crate::io::buf_reader::BufReader>::new", "Argument[0]", "ReturnValue", "taint", "manual"]
8+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
9+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
10+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read_to_end", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
11+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncReadExt::read_to_end", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
12+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_line", "Argument[self]", "Argument[0].Reference", "taint", "manual"]
13+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_line", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"]
14+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_until", "Argument[self]", "Argument[1].Reference", "taint", "manual"]
15+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::read_until", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
16+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::fill_buf", "Argument[self]", "ReturnValue.Future.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
17+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::io::AsyncBufReadExt::lines", "Argument[self]", "ReturnValue", "taint", "manual"]
18+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "crate::stream::stream::StreamExt::next", "Argument[self]", "ReturnValue.Future.Field[crate::option::Option::Some(0)]", "taint", "manual"]
19+
- ["repo:https://github.com/rust-lang/futures-rs:futures-util", "<crate::io::buf_reader::BufReader as crate::if_std::AsyncBufRead>::poll_fill_buf", "Argument[self].Reference", "ReturnValue.Field[crate::task::poll::Poll::Ready(0)].Field[crate::result::Result::Ok(0)]", "taint", "manual"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/rust-all
4+
extensible: sourceModel
5+
data:
6+
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::client::client_conn::connection::ClientConnection>::new", "ReturnValue.Field[crate::result::Result::Ok(0)]", "remote", "manual"]
7+
- addsTo:
8+
pack: codeql/rust-all
9+
extensible: summaryModel
10+
data:
11+
- ["repo:https://github.com/quininer/futures-rustls:futures-rustls", "<crate::TlsConnector>::connect", "Argument[1]", "ReturnValue.Future.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
12+
- ["repo:https://github.com/quininer/futures-rustls:futures-rustls", "<crate::client::TlsStream as crate::if_std::AsyncRead>::poll_read", "Argument[self].Reference", "Argument[1].Reference", "taint", "manual"]
13+
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::conn::ConnectionCommon>::reader", "Argument[self]", "ReturnValue", "taint", "manual"]
14+
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::conn::connection::Reader as crate::io::Read>::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"]

rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
multipleMethodCallTargets
2+
| test.rs:618:25:618:49 | address.to_socket_addrs() | file://:0:0:0:0 | fn to_socket_addrs |
3+
| test.rs:618:25:618:49 | address.to_socket_addrs() | file://:0:0:0:0 | fn to_socket_addrs |
4+
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
5+
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
6+
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
7+
| test_futures_io.rs:61:22:61:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
8+
| test_futures_io.rs:61:22:61:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
9+
| test_futures_io.rs:68:23:68:67 | ... .poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
10+
| test_futures_io.rs:68:23:68:67 | ... .poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
11+
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
12+
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
13+
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read |
14+
| test_futures_io.rs:115:22:115:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
15+
| test_futures_io.rs:115:22:115:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf |
116
multiplePathResolutions
217
| test.rs:112:62:112:73 | ...::from | file://:0:0:0:0 | fn from |
318
| test.rs:112:62:112:73 | ...::from | file://:0:0:0:0 | fn from |
@@ -29,36 +44,44 @@ multiplePathResolutions
2944
| test.rs:119:58:119:69 | ...::from | file://:0:0:0:0 | fn from |
3045
| test.rs:119:58:119:69 | ...::from | file://:0:0:0:0 | fn from |
3146
| test.rs:119:58:119:69 | ...::from | file://:0:0:0:0 | fn from |
32-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
33-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
34-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
35-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
36-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
37-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
38-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
39-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
40-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
41-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
42-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
43-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
44-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
45-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
46-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
47-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
48-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
49-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
50-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
51-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
52-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
53-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
54-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
55-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
56-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
57-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
58-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
59-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
60-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
61-
| test.rs:775:50:775:61 | ...::from | file://:0:0:0:0 | fn from |
47+
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
48+
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
49+
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
50+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
51+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
52+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
53+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
54+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
55+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
56+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
57+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
58+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
59+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
60+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
61+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
62+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
63+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
64+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
65+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
66+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
67+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
68+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
69+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
70+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
71+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
72+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
73+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
74+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
75+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
76+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
77+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
78+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
79+
| test.rs:806:50:806:61 | ...::from | file://:0:0:0:0 | fn from |
80+
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
81+
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
82+
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from |
83+
| test_futures_io.rs:144:26:144:43 | ...::with_capacity | file://:0:0:0:0 | fn with_capacity |
84+
| test_futures_io.rs:144:26:144:43 | ...::with_capacity | file://:0:0:0:0 | fn with_capacity |
6285
multipleCanonicalPaths
6386
| file://:0:0:0:0 | fn to_ordering | file://:0:0:0:0 | Crate(typenum@1.18.0) | <typenum::Equal as core::cmp::Ord>::to_ordering |
6487
| file://:0:0:0:0 | fn to_ordering | file://:0:0:0:0 | Crate(typenum@1.18.0) | <typenum::Equal as typenum::marker_traits::Ord>::to_ordering |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module MyFlowConfig implements DataFlow::ConfigSig {
1010
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource }
1111

1212
predicate isSink(DataFlow::Node sink) {
13-
any(CallExpr call | call.getFunction().(PathExpr).getResolvedPath() = "crate::test::sink")
13+
any(CallExpr call | call.getFunction().(PathExpr).getResolvedPath().matches("%::sink"))
1414
.getArgList()
1515
.getAnArg() = sink.asExpr().getExpr()
1616
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@
7575
| test.rs:619:26:619:61 | ...::connect_timeout | Flow source 'RemoteSource' of type remote (DEFAULT). |
7676
| test.rs:671:28:671:57 | ...::connect | Flow source 'RemoteSource' of type remote (DEFAULT). |
7777
| test.rs:753:22:753:49 | ...::connect | Flow source 'RemoteSource' of type remote (DEFAULT). |
78-
| test.rs:775:16:775:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
79-
| test.rs:775:16:775:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
78+
| test.rs:779:22:779:50 | ...::new | Flow source 'RemoteSource' of type remote (DEFAULT). |
79+
| test.rs:806:16:806:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
80+
| test.rs:806:16:806:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
81+
| test_futures_io.rs:19:15:19:32 | ...::connect | Flow source 'RemoteSource' of type remote (DEFAULT). |
8082
| web_frameworks.rs:12:31:12:31 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |
8183
| web_frameworks.rs:12:31:12:31 | a | Flow source 'RemoteSource' of type remote (DEFAULT). |
8284
| web_frameworks.rs:21:31:21:35 | TuplePat | Flow source 'RemoteSource' of type remote (DEFAULT). |

rust/ql/test/library-tests/dataflow/sources/options.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ qltest_dependencies:
1313
- actix-web = { version = "4.10.2" }
1414
- axum = { version = "0.8.4" }
1515
- serde_json = { version = "1.0.140" }
16+
- rustls = { version = "0.23.27" }
17+
- futures-rustls = { version = "0.26.0" }
18+
- async-std = { version = "1.13.1" }

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,37 @@ async fn test_std_to_tokio_tcpstream() -> std::io::Result<()> {
770770
Ok(())
771771
}
772772

773+
fn test_rustls() -> std::io::Result<()> {
774+
let config = rustls::ClientConfig::builder()
775+
.with_root_certificates(rustls::RootCertStore::empty())
776+
.with_no_client_auth();
777+
let server_name = rustls::pki_types::ServerName::try_from("www.example.com").unwrap();
778+
let config_arc = std::sync::Arc::new(config);
779+
let mut client = rustls::ClientConnection::new(config_arc, server_name).unwrap(); // $ Alert[rust/summary/taint-sources]
780+
let mut reader = client.reader();
781+
sink(&reader); // $ hasTaintFlow=config_arc
782+
783+
{
784+
let mut buffer = [0u8; 100];
785+
let _bytes = reader.read(&mut buffer)?;
786+
sink(&buffer); // $ hasTaintFlow=config_arc
787+
}
788+
789+
{
790+
let mut buffer = Vec::<u8>::new();
791+
let _bytes = reader.read_to_end(&mut buffer)?;
792+
sink(&buffer); // $ hasTaintFlow=config_arc
793+
}
794+
795+
{
796+
let mut buffer = String::new();
797+
let _bytes = reader.read_to_string(&mut buffer)?;
798+
sink(&buffer); // $ hasTaintFlow=config_arc
799+
}
800+
801+
Ok(())
802+
}
803+
773804
#[tokio::main]
774805
async fn main() -> Result<(), Box<dyn std::error::Error>> {
775806
let case = std::env::args().nth(1).unwrap_or(String::from("1")).parse::<i64>().unwrap(); // $ Alert[rust/summary/taint-sources]
@@ -849,5 +880,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
849880
Err(e) => println!("error: {}", e),
850881
}
851882

883+
println!("test_rustls...");
884+
match test_rustls() {
885+
Ok(_) => println!("complete"),
886+
Err(e) => println!("error: {}", e),
887+
}
888+
852889
Ok(())
853890
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
fn sink<T>(_: T) { }
2+
3+
// --- tests ---
4+
5+
use std::pin::Pin;
6+
use std::task::{Context, Poll};
7+
use std::io;
8+
use futures::io::AsyncRead;
9+
use futures::io::AsyncReadExt;
10+
use futures::io::AsyncBufRead;
11+
use futures::io::AsyncBufReadExt;
12+
use futures::StreamExt;
13+
use futures_rustls::{TlsConnector};
14+
use async_std::sync::Arc;
15+
use async_std::net::TcpStream;
16+
17+
async fn test_futures_rustls_futures_io() -> io::Result<()> {
18+
let url = "www.example.com:443";
19+
let tcp = TcpStream::connect(url).await?; // $ Alert[rust/summary/taint-sources]
20+
sink(&tcp); // $ hasTaintFlow=url
21+
let config = rustls::ClientConfig::builder()
22+
.with_root_certificates(rustls::RootCertStore::empty())
23+
.with_no_client_auth();
24+
let connector = TlsConnector::from(Arc::new(config));
25+
let server_name = rustls::pki_types::ServerName::try_from("www.example.com").unwrap();
26+
let mut reader = connector.connect(server_name, tcp).await?;
27+
sink(&reader); // $ hasTaintFlow=url
28+
29+
{
30+
// using the `AsyncRead` trait (low-level)
31+
let mut buffer = [0u8; 64];
32+
let mut pinned = Pin::new(&mut reader);
33+
sink(&pinned); // $ hasTaintFlow=url
34+
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
35+
let bytes_read = pinned.poll_read(&mut cx, &mut buffer);
36+
if let Poll::Ready(Ok(n)) = bytes_read {
37+
sink(&buffer); // $ hasTaintFlow=url
38+
sink(&buffer[..n]); // $ hasTaintFlow=url
39+
}
40+
}
41+
42+
{
43+
// using the `AsyncReadExt::read` extension method (higher-level)
44+
let mut buffer1 = [0u8; 64];
45+
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader, &mut buffer1).await?;
46+
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url
47+
48+
let mut buffer2 = [0u8; 64];
49+
let bytes_read2 = reader.read(&mut buffer2).await?;
50+
sink(&buffer2[..bytes_read2]); // $ hasTaintFlow=url
51+
}
52+
53+
let mut reader2 = futures::io::BufReader::new(reader);
54+
sink(&reader2); // $ hasTaintFlow=url
55+
56+
{
57+
// using the `AsyncBufRead` trait (low-level)
58+
let mut pinned = Pin::new(&mut reader2);
59+
sink(&pinned); // $ hasTaintFlow=url
60+
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
61+
let buffer = pinned.poll_fill_buf(&mut cx);
62+
if let Poll::Ready(Ok(buf)) = buffer {
63+
sink(&buffer); // $ MISSING: hasTaintFlow=url
64+
sink(buf); // $ MISSING: hasTaintFlow=url
65+
}
66+
67+
// using the `AsyncBufRead` trait (alternative syntax)
68+
let buffer2 = Pin::new(&mut reader2).poll_fill_buf(&mut cx);
69+
match (buffer2) {
70+
Poll::Ready(Ok(buf)) => {
71+
sink(&buffer2); // $ MISSING: hasTaintFlow=url
72+
sink(buf); // $ MISSING: hasTaintFlow=url
73+
}
74+
_ => {
75+
// ...
76+
}
77+
}
78+
}
79+
80+
{
81+
// using the `AsyncBufReadExt::fill_buf` extension method (higher-level)
82+
let buffer = reader2.fill_buf().await?;
83+
sink(buffer); // $ hasTaintFlow=url
84+
}
85+
86+
{
87+
// using the `AsyncRead` trait (low-level)
88+
let mut buffer = [0u8; 64];
89+
let mut pinned = Pin::new(&mut reader2);
90+
sink(&pinned); // $ hasTaintFlow=url
91+
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
92+
let bytes_read = pinned.poll_read(&mut cx, &mut buffer);
93+
sink(&buffer); // $ MISSING: hasTaintFlow=url
94+
if let Poll::Ready(Ok(n)) = bytes_read {
95+
sink(&buffer[..n]); // $ MISSING: hasTaintFlow=url
96+
}
97+
}
98+
99+
{
100+
// using the `AsyncReadExt::read` extension method (higher-level)
101+
let mut buffer1 = [0u8; 64];
102+
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader2, &mut buffer1).await?;
103+
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url
104+
105+
let mut buffer2 = [0u8; 64];
106+
let bytes_read2 = reader2.read(&mut buffer2).await?;
107+
sink(&buffer2[..bytes_read2]); // $ hasTaintFlow=url
108+
}
109+
110+
{
111+
// using the `AsyncBufRead` trait (low-level)
112+
let mut pinned = Pin::new(&mut reader2);
113+
sink(&pinned); // $ hasTaintFlow=url
114+
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
115+
let buffer = pinned.poll_fill_buf(&mut cx);
116+
sink(&buffer); // $ MISSING: hasTaintFlow=url
117+
if let Poll::Ready(Ok(buf)) = buffer {
118+
sink(buf); // $ MISSING: hasTaintFlow=url
119+
}
120+
}
121+
122+
{
123+
// using the `AsyncBufReadExt::fill_buf` extension method (higher-level)
124+
let buffer = reader2.fill_buf().await?;
125+
sink(buffer); // $ hasTaintFlow=url
126+
}
127+
128+
{
129+
// using the `AsyncBufReadExt::read_until` extension method
130+
let mut line = Vec::new();
131+
let _bytes_read = reader2.read_until(b'\n', &mut line).await?;
132+
sink(&line); // $ hasTaintFlow=url
133+
}
134+
135+
{
136+
// using the `AsyncBufReadExt::read_line` extension method
137+
let mut line = String::new();
138+
let _bytes_read = reader2.read_line(&mut line).await?;
139+
sink(&line); // $ hasTaintFlow=url
140+
}
141+
142+
{
143+
// using the `AsyncBufReadExt::read_to_end` extension method
144+
let mut buffer = Vec::with_capacity(1024);
145+
let _bytes_read = reader2.read_to_end(&mut buffer).await?;
146+
sink(&buffer); // $ hasTaintFlow=url
147+
}
148+
149+
{
150+
// using the `AsyncBufReadExt::lines` extension method
151+
let mut lines_stream = reader2.lines();
152+
sink(lines_stream.next().await.unwrap()); // $ hasTaintFlow=url
153+
while let Some(line) = lines_stream.next().await {
154+
sink(line.unwrap()); // $ MISSING: hasTaintFlow
155+
}
156+
}
157+
158+
Ok(())
159+
}

0 commit comments

Comments
 (0)