-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rust: Model futures-io, rustls, futures-rustls #19626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
544af7f
a5e1702
b78d51e
13f6de9
84c72f6
4d51a15
10f894b
49dabdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extensions: | ||
- addsTo: | ||
pack: codeql/rust-all | ||
extensible: sourceModel | ||
data: | ||
- ["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"] |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,14 @@ | ||||||||
extensions: | ||||||||
- addsTo: | ||||||||
pack: codeql/rust-all | ||||||||
extensible: sourceModel | ||||||||
data: | ||||||||
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::client::client_conn::connection::ClientConnection>::new", "ReturnValue.Field[crate::result::Result::Ok(0)]", "remote", "manual"] | ||||||||
- addsTo: | ||||||||
pack: codeql/rust-all | ||||||||
extensible: summaryModel | ||||||||
data: | ||||||||
- ["repo:https://github.com/quininer/futures-rustls:futures-rustls", "<crate::TlsConnector>::connect", "Argument[1]", "ReturnValue.Future.Field[crate::result::Result::Ok(0)]", "taint", "manual"] | ||||||||
- ["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"] | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice try, but it doesn't help. Hopefully when we have support for MaD trait models, we can clean this stuff up. |
||||||||
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::conn::ConnectionCommon>::reader", "Argument[self]", "ReturnValue", "taint", "manual"] | ||||||||
- ["repo:https://github.com/rustls/rustls:rustls", "<crate::conn::connection::Reader as crate::io::Read>::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,25 @@ | ||
multipleMethodCallTargets | ||
| test.rs:618:25:618:49 | address.to_socket_addrs() | file://:0:0:0:0 | fn to_socket_addrs | | ||
| test.rs:618:25:618:49 | address.to_socket_addrs() | file://:0:0:0:0 | fn to_socket_addrs | | ||
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:35:26:35:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:61:22:61:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
| test_futures_io.rs:61:22:61:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
| test_futures_io.rs:68:23:68:67 | ... .poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
| test_futures_io.rs:68:23:68:67 | ... .poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:92:26:92:63 | pinned.poll_read(...) | file://:0:0:0:0 | fn poll_read | | ||
| test_futures_io.rs:115:22:115:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
| test_futures_io.rs:115:22:115:50 | pinned.poll_fill_buf(...) | file://:0:0:0:0 | fn poll_fill_buf | | ||
multiplePathResolutions | ||
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
| test.rs:777:23:777:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
| test_futures_io.rs:25:23:25:61 | ...::try_from | file://:0:0:0:0 | fn try_from | | ||
multipleCanonicalPaths | ||
| file://:0:0:0:0 | fn to_ordering | file://:0:0:0:0 | Crate([email protected]) | <typenum::Equal as core::cmp::Ord>::to_ordering | | ||
| file://:0:0:0:0 | fn to_ordering | file://:0:0:0:0 | Crate([email protected]) | <typenum::Equal as typenum::marker_traits::Ord>::to_ordering | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
fn sink<T>(_: T) { } | ||
|
||
// --- tests --- | ||
|
||
use std::pin::Pin; | ||
use std::task::{Context, Poll}; | ||
use std::io; | ||
use futures::io::AsyncRead; | ||
use futures::io::AsyncReadExt; | ||
use futures::io::AsyncBufRead; | ||
use futures::io::AsyncBufReadExt; | ||
use futures::StreamExt; | ||
use futures_rustls::{TlsConnector}; | ||
use async_std::sync::Arc; | ||
use async_std::net::TcpStream; | ||
|
||
async fn test_futures_rustls_futures_io() -> io::Result<()> { | ||
let url = "www.example.com:443"; | ||
let tcp = TcpStream::connect(url).await?; // $ Alert[rust/summary/taint-sources] | ||
sink(&tcp); // $ hasTaintFlow=url | ||
let config = rustls::ClientConfig::builder() | ||
.with_root_certificates(rustls::RootCertStore::empty()) | ||
.with_no_client_auth(); | ||
let connector = TlsConnector::from(Arc::new(config)); | ||
let server_name = rustls::pki_types::ServerName::try_from("www.example.com").unwrap(); | ||
let mut reader = connector.connect(server_name, tcp).await?; | ||
sink(&reader); // $ hasTaintFlow=url | ||
|
||
{ | ||
// using the `AsyncRead` trait (low-level) | ||
let mut buffer = [0u8; 64]; | ||
let mut pinned = Pin::new(&mut reader); | ||
sink(&pinned); // $ hasTaintFlow=url | ||
let mut cx = Context::from_waker(futures::task::noop_waker_ref()); | ||
let bytes_read = pinned.poll_read(&mut cx, &mut buffer); | ||
if let Poll::Ready(Ok(n)) = bytes_read { | ||
sink(&buffer); // $ hasTaintFlow=url | ||
sink(&buffer[..n]); // $ hasTaintFlow=url | ||
} | ||
} | ||
|
||
{ | ||
// using the `AsyncReadExt::read` extension method (higher-level) | ||
let mut buffer1 = [0u8; 64]; | ||
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader, &mut buffer1).await?; | ||
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url | ||
|
||
let mut buffer2 = [0u8; 64]; | ||
let bytes_read2 = reader.read(&mut buffer2).await?; | ||
sink(&buffer2[..bytes_read2]); // $ hasTaintFlow=url | ||
} | ||
|
||
let mut reader2 = futures::io::BufReader::new(reader); | ||
sink(&reader2); // $ hasTaintFlow=url | ||
|
||
{ | ||
// using the `AsyncBufRead` trait (low-level) | ||
let mut pinned = Pin::new(&mut reader2); | ||
sink(&pinned); // $ hasTaintFlow=url | ||
let mut cx = Context::from_waker(futures::task::noop_waker_ref()); | ||
let buffer = pinned.poll_fill_buf(&mut cx); | ||
if let Poll::Ready(Ok(buf)) = buffer { | ||
sink(&buffer); // $ MISSING: hasTaintFlow=url | ||
sink(buf); // $ MISSING: hasTaintFlow=url | ||
} | ||
|
||
// using the `AsyncBufRead` trait (alternative syntax) | ||
let buffer2 = Pin::new(&mut reader2).poll_fill_buf(&mut cx); | ||
match (buffer2) { | ||
Poll::Ready(Ok(buf)) => { | ||
sink(&buffer2); // $ MISSING: hasTaintFlow=url | ||
sink(buf); // $ MISSING: hasTaintFlow=url | ||
} | ||
_ => { | ||
// ... | ||
} | ||
} | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::fill_buf` extension method (higher-level) | ||
let buffer = reader2.fill_buf().await?; | ||
sink(buffer); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncRead` trait (low-level) | ||
let mut buffer = [0u8; 64]; | ||
let mut pinned = Pin::new(&mut reader2); | ||
sink(&pinned); // $ hasTaintFlow=url | ||
let mut cx = Context::from_waker(futures::task::noop_waker_ref()); | ||
let bytes_read = pinned.poll_read(&mut cx, &mut buffer); | ||
sink(&buffer); // $ MISSING: hasTaintFlow=url | ||
if let Poll::Ready(Ok(n)) = bytes_read { | ||
sink(&buffer[..n]); // $ MISSING: hasTaintFlow=url | ||
} | ||
} | ||
|
||
{ | ||
// using the `AsyncReadExt::read` extension method (higher-level) | ||
let mut buffer1 = [0u8; 64]; | ||
let bytes_read1 = futures::io::AsyncReadExt::read(&mut reader2, &mut buffer1).await?; | ||
sink(&buffer1[..bytes_read1]); // $ hasTaintFlow=url | ||
|
||
let mut buffer2 = [0u8; 64]; | ||
let bytes_read2 = reader2.read(&mut buffer2).await?; | ||
sink(&buffer2[..bytes_read2]); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncBufRead` trait (low-level) | ||
let mut pinned = Pin::new(&mut reader2); | ||
sink(&pinned); // $ hasTaintFlow=url | ||
let mut cx = Context::from_waker(futures::task::noop_waker_ref()); | ||
let buffer = pinned.poll_fill_buf(&mut cx); | ||
sink(&buffer); // $ MISSING: hasTaintFlow=url | ||
if let Poll::Ready(Ok(buf)) = buffer { | ||
sink(buf); // $ MISSING: hasTaintFlow=url | ||
} | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::fill_buf` extension method (higher-level) | ||
let buffer = reader2.fill_buf().await?; | ||
sink(buffer); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::read_until` extension method | ||
let mut line = Vec::new(); | ||
let _bytes_read = reader2.read_until(b'\n', &mut line).await?; | ||
sink(&line); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::read_line` extension method | ||
let mut line = String::new(); | ||
let _bytes_read = reader2.read_line(&mut line).await?; | ||
sink(&line); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::read_to_end` extension method | ||
let mut buffer = Vec::with_capacity(1024); | ||
let _bytes_read = reader2.read_to_end(&mut buffer).await?; | ||
sink(&buffer); // $ hasTaintFlow=url | ||
} | ||
|
||
{ | ||
// using the `AsyncBufReadExt::lines` extension method | ||
let mut lines_stream = reader2.lines(); | ||
sink(lines_stream.next().await.unwrap()); // $ hasTaintFlow=url | ||
while let Some(line) = lines_stream.next().await { | ||
sink(line.unwrap()); // $ MISSING: hasTaintFlow | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] These two
read
rules only differ by.Reference
. Consider consolidating into a single pattern (e.g., matchArgument[self]
) to reduce duplication and maintenance overhead.Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's missing data flow through certain implicit dereferences, when that's fixed we can get rid of the duplicate models.