updated dependencies

This commit is contained in:
Mick Grove 2026-04-01 17:25:19 -07:00
commit e2664e33ed
4 changed files with 60 additions and 21 deletions

View file

@ -154,7 +154,7 @@ base32 = "0.5.1"
crossbeam-skiplist = "0.1.3"
tokio-postgres = { version = "0.7", default-features = false, features = ["runtime"] }
mongodb = { version = "3.4", default-features = false, features = ["rustls-tls", "aws-auth", "compat-3-0-0", "dns-resolver"] }
mysql_async = { version = "0.36.1", default-features = false, features = ["default-rustls"] }
mysql_async = { version = "0.36.2", default-features = false, features = ["default-rustls"] }
bson = { version = "3.1.0", features = ["serde"] }
ring = "0.17.14"
pem = "3.0.6"
@ -195,7 +195,7 @@ tree_magic_mini = "3.2"
content_inspector = "0.2.4"
rustc-hash = "2.1.1"
bzip2-rs = "0.1.2"
zip = { version = "2.4.2", default-features = false, features = ["deflate", "deflate64", "time"] }
zip = { version = "8.5.0", default-features = false, features = ["deflate", "deflate64", "time"] }
tar = "0.4.44"
lzma-rs = "0.3.0"
asar = "0.3.0"
@ -282,7 +282,7 @@ temp-env = "0.3.6"
wiremock = "0.6.5"
git2 = { version = "0.20.3", default-features = false }
rand_chacha = "0.10.0"
testcontainers = "0.15.0"
testcontainers = "0.27.2"
[profile.release]
debug = false

View file

@ -173,7 +173,7 @@ hex = { workspace = true, optional = true }
url = { version = "2.5.7", optional = true }
bson = { version = "3.1.0", features = ["serde"], optional = true }
mongodb = { version = "3.4", default-features = false, features = ["rustls-tls", "aws-auth", "compat-3-0-0", "dns-resolver"], optional = true }
mysql_async = { version = "0.36.1", default-features = false, features = ["default-rustls"], optional = true }
mysql_async = { version = "0.36.2", default-features = false, features = ["default-rustls"], optional = true }
tokio-postgres = { version = "0.7", default-features = false, features = ["runtime"], optional = true }
tokio-postgres-rustls = { version = "0.13.0", optional = true }
rustls = { version = "0.23.35", optional = true }

View file

@ -348,11 +348,12 @@ pub fn decompress_file_to_temp(path: &Path) -> Result<(CompressedContent, TempDi
#[cfg(test)]
mod tests {
use std::fs::File;
use std::{fs::File, io::Write};
use flate2::{write::GzEncoder, Compression};
use tar::Builder;
use tempfile::tempdir;
use zip::{write::SimpleFileOptions, CompressionMethod, ZipWriter};
use super::{decompress_once, CompressedContent};
@ -454,6 +455,43 @@ mod tests {
Ok(())
}
#[test]
fn smoke_decompress_zip_archive() -> anyhow::Result<()> {
let dir = tempdir()?;
let zip_path = dir.path().join("payload.zip");
let github_pat = "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"; // this is not a real secret
{
let file = File::create(&zip_path)?;
let mut zip = ZipWriter::new(file);
let options = SimpleFileOptions::default()
.compression_method(CompressionMethod::Deflated)
.unix_permissions(0o644);
zip.start_file("nested/secret.txt", options)?;
zip.write_all(format!("token={github_pat}\n").as_bytes())?;
zip.finish()?;
}
let tmp = tempdir()?;
let content = decompress_once(&zip_path, Some(tmp.path()))?;
if let CompressedContent::ArchiveFiles(files) = content {
let mut found = false;
for (logical, path) in files {
if logical.ends_with("!nested/secret.txt") {
let txt = std::fs::read_to_string(&path)?;
assert!(txt.contains(github_pat));
found = true;
}
}
assert!(found, "did not find nested/secret.txt in ArchiveFiles");
} else {
panic!("expected ArchiveFiles for zip archive, got {:?}", content);
}
Ok(())
}
/// 3) Nested archive: outer.tar.gz ──▶ outer.tar (contains inner.tar.gz) └──▶ inner.tar.gz
/// ──▶ inner.tar (contains secret.txt)
#[test]

View file

@ -8,7 +8,11 @@ use std::time::{Duration, Instant};
use anyhow::{anyhow, Result};
use kingfisher::validation::{validate_mysql, validate_postgres};
use testcontainers::{clients::Cli, core::WaitFor, GenericImage};
use testcontainers::{
core::{IntoContainerPort, WaitFor},
runners::AsyncRunner,
GenericImage, ImageExt,
};
use tokio::{net::TcpStream, time::sleep};
const HOST_ALIAS: &str = "kingfisherlocal";
@ -40,15 +44,15 @@ async fn wait_for_port(host: &str, port: u16) -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore]
async fn validates_mysql_secret_against_testcontainer() -> Result<()> {
let docker = Cli::default();
let image = GenericImage::new("mysql", "8.4")
let container = GenericImage::new("mysql", "8.4")
.with_exposed_port(3306.tcp())
.with_wait_for(WaitFor::message_on_stdout("MySQL init process done. Ready for start up."))
.with_env_var("MYSQL_ROOT_PASSWORD", "secret")
.with_env_var("MYSQL_DATABASE", "app")
.with_env_var("MYSQL_ROOT_HOST", "%")
.with_wait_for(WaitFor::message_on_stdout("MySQL init process done. Ready for start up."));
let container = docker.run(image);
let port = container.get_host_port_ipv4(3306);
.start()
.await?;
let port = container.get_host_port_ipv4(3306.tcp()).await?;
wait_for_port(HOST_ALIAS, port).await?;
@ -66,21 +70,19 @@ async fn validates_mysql_secret_against_testcontainer() -> Result<()> {
);
drop(container);
drop(docker);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore]
async fn validates_postgres_secret_against_testcontainer() -> Result<()> {
let docker = Cli::default();
let image = GenericImage::new("postgres", "15")
let container = GenericImage::new("postgres", "15")
.with_exposed_port(5432.tcp())
.with_wait_for(WaitFor::message_on_stdout("database system is ready to accept connections"))
.with_env_var("POSTGRES_PASSWORD", "secret")
.with_wait_for(WaitFor::message_on_stdout(
"database system is ready to accept connections",
));
let container = docker.run(image);
let port = container.get_host_port_ipv4(5432);
.start()
.await?;
let port = container.get_host_port_ipv4(5432.tcp()).await?;
wait_for_port(HOST_ALIAS, port).await?;
@ -91,6 +93,5 @@ async fn validates_postgres_secret_against_testcontainer() -> Result<()> {
assert!(metadata.is_empty(), "expected no metadata but found {metadata:?}");
drop(container);
drop(docker);
Ok(())
}