Skip to content

Commit 544af7f

Browse files
committed
Rust: Add tests for sources involving futures-rustls and futures-io.
1 parent f5ea929 commit 544af7f

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

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" }
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?; // $ MISSING: Alert[rust/summary/taint-sources]
20+
sink(&tcp); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow=url
38+
sink(&buffer[..n]); // $ MISSING: 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]); // $ MISSING: hasTaintFlow
47+
48+
let mut buffer2 = [0u8; 64];
49+
let bytes_read2 = reader.read(&mut buffer2).await?;
50+
sink(&buffer2[..bytes_read2]); // $ MISSING: hasTaintFlow
51+
}
52+
53+
let mut reader2 = futures::io::BufReader::new(reader);
54+
sink(&reader2); // $ MISSING: hasTaintFlow
55+
56+
{
57+
// using the `AsyncBufRead` trait (low-level)
58+
let mut pinned = Pin::new(&mut reader2);
59+
sink(&pinned); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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]); // $ MISSING: hasTaintFlow
104+
105+
let mut buffer2 = [0u8; 64];
106+
let bytes_read2 = reader2.read(&mut buffer2).await?;
107+
sink(&buffer2[..bytes_read2]); // $ MISSING: hasTaintFlow
108+
}
109+
110+
{
111+
// using the `AsyncBufRead` trait (low-level)
112+
let mut pinned = Pin::new(&mut reader2);
113+
sink(&pinned); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
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); // $ MISSING: hasTaintFlow
147+
}
148+
149+
{
150+
// using the `AsyncBufReadExt::lines` extension method
151+
let mut lines_stream = reader2.lines();
152+
sink(lines_stream.next().await.unwrap()); // $ MISSING: hasTaintFlow
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)