Rust: Add test cases for the mysql_async library.

This commit is contained in:
Geoffrey White
2025-10-10 15:35:20 +01:00
parent ef93b364da
commit 883e00558a
3 changed files with 179 additions and 50 deletions

View File

@@ -1199,6 +1199,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "keyed_priority_queue"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d"
dependencies = [
"indexmap",
]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
@@ -1294,6 +1303,15 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
[[package]]
name = "lru"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f8cc7106155f10bdf99a6f379688f543ad6596a415375b36a59a054ceda1198"
dependencies = [
"hashbrown",
]
[[package]]
name = "md-5"
version = "0.10.6"
@@ -1350,7 +1368,7 @@ dependencies = [
"flate2",
"io-enum",
"libc",
"lru",
"lru 0.12.5",
"mysql_common",
"named_pipe",
"pem",
@@ -1378,6 +1396,34 @@ dependencies = [
"thiserror",
]
[[package]]
name = "mysql_async"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "277ce2f2459b2af4cc6d0a0b7892381f80800832f57c533f03e2845f4ea331ea"
dependencies = [
"bytes",
"crossbeam-queue",
"flate2",
"futures-core",
"futures-sink",
"futures-util",
"keyed_priority_queue",
"lru 0.14.0",
"mysql_common",
"pem",
"percent-encoding",
"rand 0.9.2",
"serde",
"serde_json",
"socket2 0.5.10",
"thiserror",
"tokio",
"tokio-util",
"twox-hash",
"url",
]
[[package]]
name = "mysql_common"
version = "0.35.5"
@@ -1453,7 +1499,7 @@ dependencies = [
"num-integer",
"num-iter",
"num-traits",
"rand",
"rand 0.8.5",
"smallvec",
"zeroize",
]
@@ -1762,8 +1808,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
]
[[package]]
@@ -1773,7 +1829,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
@@ -1785,6 +1851,15 @@ dependencies = [
"getrandom 0.2.16",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.3",
]
[[package]]
name = "redox_syscall"
version = "0.5.13"
@@ -1892,7 +1967,7 @@ dependencies = [
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
@@ -2110,7 +2185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
@@ -2288,7 +2363,7 @@ dependencies = [
"memchr",
"once_cell",
"percent-encoding",
"rand",
"rand 0.8.5",
"rsa",
"serde",
"sha1",
@@ -2326,7 +2401,7 @@ dependencies = [
"md-5",
"memchr",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2",
@@ -2471,6 +2546,7 @@ version = "0.0.1"
dependencies = [
"futures",
"mysql",
"mysql_async",
"reqwest",
"sqlx",
]

View File

@@ -1,54 +1,106 @@
use mysql::*;
use mysql::prelude::*;
mod sync_test
{
use mysql::*;
use mysql::prelude::*;
async fn test_mysql(url: &str) -> Result<(), Box<dyn std::error::Error>> {
// connect through a MySQL connection pool
let mut pool = Pool::new("")?; // (this test is not runnable)
let mut conn: PooledConn = pool.get_conn()?;
let mut conn2: Conn = pool.get_conn()?.unwrap();
pub fn test_mysql(url: &str) -> Result<(), Box<dyn std::error::Error>> {
// connect through a MySQL connection pool
let mut pool = Pool::new("")?; // (this test is not runnable)
let mut conn: PooledConn = pool.get_conn()?;
let mut conn2: Conn = pool.get_conn()?.unwrap();
// construct queries
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote10
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
// construct queries
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote10
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
// direct execution (safe)
let _ : Vec<i64> = conn.query(safe_query.as_str())?;
// direct execution (safe)
let _ : Vec<i64> = conn.query(safe_query.as_str())?;
// direct execution (unsafe)
let _ : Vec<i64> = conn.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Vec<Result<i64, FromRowError>> = conn.query_opt(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : i64 = conn.query_first(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Result<i64, FromRowError>= conn.query_first_opt(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_fold_opt(unsafe_query.as_str(), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_iter(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_map_opt(unsafe_query.as_str(), |_: Result<i64, FromRowError>| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Vec<i64> = conn2.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
// direct execution (unsafe)
let _ : Vec<i64> = conn.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Vec<Result<i64, FromRowError>> = conn.query_opt(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : i64 = conn.query_first(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Result<i64, FromRowError>= conn.query_first_opt(unsafe_query.as_str())?.unwrap(); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_fold_opt(unsafe_query.as_str(), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_iter(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ = conn.query_map_opt(unsafe_query.as_str(), |_: Result<i64, FromRowError>| -> () {})?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
let _ : Vec<i64> = conn2.query(unsafe_query.as_str())?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote10
// prepared queries (safe)
let stmt = conn.prep(prepared_query.as_str())?;
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),))?;
let _ : Vec<Result<i64, FromRowError>> = conn.exec_opt(&stmt, (remote_string.as_str(),))?;
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)])?;
conn.exec_drop(&stmt, (&remote_string.as_str(),));
let _ : i64 = conn.exec_first(&stmt, (remote_string.as_str(),))?.unwrap();
let _ : Result<i64, FromRowError> = conn.exec_first_opt(&stmt, (remote_string.as_str(),))?.unwrap();
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 })?;
let _ = conn.exec_fold_opt(&stmt, (remote_string.as_str(),), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?;
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),))?;
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {})?;
let _ = conn.exec_map_opt(&stmt, (remote_string.as_str(),), |_: Result<i64, FromRowError>| -> () {})?;
// prepared queries (safe)
let stmt = conn.prep(prepared_query.as_str())?;
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),))?;
let _ : Vec<Result<i64, FromRowError>> = conn.exec_opt(&stmt, (remote_string.as_str(),))?;
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)])?;
conn.exec_drop(&stmt, (&remote_string.as_str(),));
let _ : i64 = conn.exec_first(&stmt, (remote_string.as_str(),))?.unwrap();
let _ : Result<i64, FromRowError> = conn.exec_first_opt(&stmt, (remote_string.as_str(),))?.unwrap();
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 })?;
let _ = conn.exec_fold_opt(&stmt, (remote_string.as_str(),), 0, |_: i64, _: Result<i64, FromRowError>| -> i64 { 0 })?;
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),))?;
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {})?;
let _ = conn.exec_map_opt(&stmt, (remote_string.as_str(),), |_: Result<i64, FromRowError>| -> () {})?;
Ok(())
Ok(())
}
}
mod async_test
{
use mysql_async::*;
use mysql_async::prelude::*;
pub async fn test_mysql_async(url: &str) -> Result<()> {
// connect through a MySQL connection pool
let mut pool = Pool::new(""); // (this test is not runnable)
let mut conn = pool.get_conn().await?;
// construct queries
let mut remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("")); // $ MISSING: Source=remote11
let safe_query = String::from("SELECT * FROM people WHERE firstname='Alice'");
let unsafe_query = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'";
let prepared_query = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe)
// direct execution (safe)
let _ : Vec<i64> = conn.query(safe_query.as_str()).await?;
// direct execution (unsafe)
let _ : Vec<i64> = conn.query(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
conn.query_drop(unsafe_query.as_str()); // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
let _ : Option<i64> = conn.query_first(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
let _ = conn.query_fold(unsafe_query.as_str(), 0, |_: i64, _: i64| -> i64 { 0 }).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
let _ = conn.query_iter(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
let _ = conn.query_stream::<i64, &str>(unsafe_query.as_str()).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
let _ = conn.query_map(unsafe_query.as_str(), |_: i64| -> () {}).await?; // $ MISSING: sql-sink Alert[rust/sql-injection]=remote11
// prepared queries (safe)
let stmt = conn.prep(prepared_query.as_str()).await?;
let _ : Vec<i64> = conn.exec(&stmt, (remote_string.as_str(),)).await?;
let _ = conn.exec_batch(&stmt, vec![(remote_string.as_str(),)]).await?;
conn.exec_drop(&stmt, (&remote_string.as_str(),));
let _ : Option<i64> = conn.exec_first(&stmt, (remote_string.as_str(),)).await?;
let _ = conn.exec_fold(&stmt, (remote_string.as_str(),), 0, |_: i64, _: i64| -> i64 { 0 }).await?;
let _ = conn.exec_iter(&stmt, (remote_string.as_str(),)).await?;
let _ = conn.exec_stream::<i64, &Statement, (&str,)>(&stmt, (remote_string.as_str(),)).await?;
let _ = conn.exec_map(&stmt, (remote_string.as_str(),), |_: i64| -> () {}).await?;
Ok(())
}
}
fn main() {
println!("test_mysql...");
match futures::executor::block_on(test_mysql("")) {
match (sync_test::test_mysql("")) {
Ok(_) => println!(" successful!"),
Err(e) => println!(" error: {}", e),
}
println!("test_mysql_async...");
match futures::executor::block_on(async_test::test_mysql_async("")) {
Ok(_) => println!(" successful!"),
Err(e) => println!(" error: {}", e),
}

View File

@@ -4,3 +4,4 @@ qltest_dependencies:
- sqlx = { version = "0.8", features = ["mysql", "sqlite", "postgres", "runtime-async-std", "tls-native-tls"] }
- futures = { version = "0.3" }
- mysql = { version = "26.0.1" }
- mysql_async = { version = "0.36.1" }