Skip to content

Commit b57375a

Browse files
committed
Rust: Add source tests for tcp (std and tokio).
1 parent 809dd20 commit b57375a

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@
4646
| test.rs:451:21:451:39 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
4747
| test.rs:452:21:452:39 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
4848
| test.rs:460:21:460:39 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
49-
| test.rs:522:16:522:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |
49+
| test.rs:621:16:621:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |

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

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,105 @@ async fn test_tokio_file() -> std::io::Result<()> {
517517
Ok(())
518518
}
519519

520+
use std::net::ToSocketAddrs;
521+
522+
async fn test_std_tcpstream(case: i64) -> std::io::Result<()> { // Result<(), Box<dyn Error>>
523+
// using std::net to fetch a web page
524+
let address = "example.com:80";
525+
526+
if case == 1 {
527+
// create the connection
528+
let mut stream = std::net::TcpStream::connect(address)?;
529+
530+
// send request
531+
let _ = stream.write_all(b"GET / HTTP/1.1\nHost:example.com\n\n");
532+
533+
// read response
534+
let mut buffer = vec![0; 32 * 1024];
535+
let _ = stream.read(&mut buffer); // $ MISSING: Alert[rust/summary/taint-sources]
536+
537+
println!("data = {:?}", buffer);
538+
sink(&buffer); // $ MISSING: hasTaintFlow
539+
sink(buffer[0]); // $ MISSING: hasTaintFlow
540+
541+
let buffer_string = String::from_utf8_lossy(&buffer);
542+
println!("string = {}", buffer_string);
543+
sink(buffer_string); // $ MISSING: hasTaintFlow
544+
} else {
545+
// create the connection
546+
let sock_addr = address.to_socket_addrs().unwrap().next().unwrap();
547+
let mut stream = std::net::TcpStream::connect_timeout(&sock_addr, std::time::Duration::new(1, 0))?;
548+
549+
// send request
550+
let _ = stream.write_all(b"GET / HTTP/1.1\nHost:example.com\n\n");
551+
552+
// read response
553+
match case {
554+
2 => {
555+
let mut reader = std::io::BufReader::new(stream).take(256);
556+
let mut line = String::new();
557+
loop {
558+
match reader.read_line(&mut line) { // $ MISSING: Alert[rust/summary/taint-sources]
559+
Ok(0) => {
560+
println!("end");
561+
break;
562+
}
563+
Ok(_n) => {
564+
println!("line = {}", line);
565+
sink(&line); // $ MISSING: hasTaintFlow
566+
line.clear();
567+
}
568+
Err(e) => {
569+
println!("error: {}", e);
570+
break;
571+
}
572+
}
573+
}
574+
}
575+
3 => {
576+
let reader = std::io::BufReader::new(stream.try_clone()?).take(256);
577+
for line in reader.lines() { // $ MISSING: Alert[rust/summary/taint-sources]
578+
if let Ok(string) = line {
579+
println!("line = {}", string);
580+
sink(string); // $ MISSING: hasTaintFlow
581+
}
582+
}
583+
}
584+
_ => {}
585+
}
586+
}
587+
588+
Ok(())
589+
}
590+
591+
use tokio::io::AsyncWriteExt;
592+
593+
async fn test_tokio_tcpstream() -> std::io::Result<()> {
594+
// using tokio::io to fetch a web page
595+
let address = "example.com:80";
596+
597+
// create the connection
598+
println!("connecting to {}...", address);
599+
let mut tokio_stream = tokio::net::TcpStream::connect(address).await?;
600+
601+
// send request
602+
tokio_stream.write_all(b"GET / HTTP/1.1\nHost:example.com\n\n").await?;
603+
604+
// read response
605+
let mut buffer = vec![0; 32 * 1024];
606+
let n = tokio_stream.read(&mut buffer).await?; // $ MISSING: Alert[rust/summary/taint-sources]
607+
608+
println!("data = {:?}", buffer);
609+
sink(&buffer); // $ MISSING: hasTaintFlow
610+
sink(buffer[0]); // $ MISSING: hasTaintFlow
611+
612+
let buffer_string = String::from_utf8_lossy(&buffer[..n]);
613+
println!("string = {}", buffer_string);
614+
sink(buffer_string); // $ MISSING: hasTaintFlow
615+
616+
Ok(())
617+
}
618+
520619
#[tokio::main]
521620
async fn main() -> Result<(), Box<dyn std::error::Error>> {
522621
let case = std::env::args().nth(1).unwrap_or(String::from("1")).parse::<i64>().unwrap(); // $ Alert[rust/summary/taint-sources]
@@ -572,5 +671,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
572671
Err(e) => println!("error: {}", e),
573672
}
574673

674+
println!("test_std_tcpstream...");
675+
match futures::executor::block_on(test_std_tcpstream(case)) {
676+
Ok(_) => println!("complete"),
677+
Err(e) => println!("error: {}", e),
678+
}
679+
680+
println!("test_tokio_tcpstream...");
681+
match futures::executor::block_on(test_tokio_tcpstream()) {
682+
Ok(_) => println!("complete"),
683+
Err(e) => println!("error: {}", e),
684+
}
685+
575686
Ok(())
576687
}

0 commit comments

Comments
 (0)