Switched compression dependencies to pure-Rust bzip2/lzma implementations and pared zip features to avoid C-based codecs for bz2/xz handling.

This commit is contained in:
Mick Grove 2026-01-23 09:52:11 -08:00
commit 216fc1dbdc
2 changed files with 27 additions and 13 deletions

View file

@ -10,6 +10,10 @@ rules:
password \s+ ([^\s]+)
min_entropy: 3.3
confidence: medium
pattern_requirements:
ignore_if_contains:
- '${'
- '$('
examples:
- 'machine api.github.com login ziggy^stardust password 012345abcdef'
- |

View file

@ -175,22 +175,32 @@ fn handle_asar_archive_in_memory(buffer: &[u8], archive_path: &Path) -> Result<C
}
}
fn stream_to_file<R: Read>(mut decoder: R, out_path: &Path) -> Result<CompressedContent> {
if !is_safe_extract_path(out_path) {
anyhow::bail!("unsafe path during decompression: {}", out_path.display());
/// Validate and open a file for reading, checking for path traversal attacks.
fn safe_open_for_read(path: &Path) -> Result<fs::File> {
if !is_safe_extract_path(path) {
anyhow::bail!("unsafe input path during decompression: {}", path.display());
}
let mut out_file = fs::File::create(out_path)?;
Ok(fs::File::open(path)?)
}
/// Validate and create a file for writing, checking for path traversal attacks.
fn safe_create_for_write(path: &Path) -> Result<fs::File> {
if !is_safe_extract_path(path) {
anyhow::bail!("unsafe output path during decompression: {}", path.display());
}
Ok(fs::File::create(path)?)
}
fn stream_to_file<R: Read>(mut decoder: R, out_path: &Path) -> Result<CompressedContent> {
let mut out_file = safe_create_for_write(out_path)?;
std::io::copy(&mut decoder, &mut out_file)?;
Ok(CompressedContent::RawFile(out_path.to_owned()))
}
fn stream_xz_to_file(path: &Path, out_path: &Path) -> Result<CompressedContent> {
if !is_safe_extract_path(out_path) {
anyhow::bail!("unsafe path during decompression: {}", out_path.display());
}
let input = fs::File::open(path)?;
let input = safe_open_for_read(path)?;
let mut reader = BufReader::new(input);
let mut out_file = fs::File::create(out_path)?;
let mut out_file = safe_create_for_write(out_path)?;
xz_decompress(&mut reader, &mut out_file)?;
Ok(CompressedContent::RawFile(out_path.to_owned()))
}
@ -201,7 +211,7 @@ one *step* of decompression
fn decompress_once(path: &Path, base_dir: Option<&Path>) -> Result<CompressedContent> {
let extension = path.extension().and_then(|ext| ext.to_str()).map(|s| s.to_ascii_lowercase());
let mut file = fs::File::open(path)?;
let mut file = safe_open_for_read(path)?;
if let Some(ext) = extension.as_deref() {
match ext {
@ -227,12 +237,12 @@ fn decompress_once(path: &Path, base_dir: Option<&Path>) -> Result<CompressedCon
}
"gz" | "gzip" => {
let out_path = make_output_path(path, base_dir, "decomp.tar");
let decoder = GzDecoder::new(fs::File::open(path)?);
let decoder = GzDecoder::new(safe_open_for_read(path)?);
return stream_to_file(decoder, &out_path);
}
"bz2" | "bzip2" => {
let out_path = make_output_path(path, base_dir, "decomp.tar");
let decoder = DecoderReader::new(fs::File::open(path)?);
let decoder = DecoderReader::new(safe_open_for_read(path)?);
return stream_to_file(decoder, &out_path);
}
"xz" => {
@ -241,7 +251,7 @@ fn decompress_once(path: &Path, base_dir: Option<&Path>) -> Result<CompressedCon
}
"zlib" => {
let out_path = make_output_path(path, base_dir, "decomp.tar");
let decoder = ZlibDecoder::new(fs::File::open(path)?);
let decoder = ZlibDecoder::new(safe_open_for_read(path)?);
return stream_to_file(decoder, &out_path);
}
_ => {}