Adding support for scanning Docker images

This commit is contained in:
Mick Grove 2025-07-27 17:54:26 -07:00
commit f48ea7ca0a
3 changed files with 35 additions and 4 deletions

View file

@ -256,12 +256,28 @@ fn make_output_path(path: &Path, base: Option<&Path>, extension: &str) -> PathBu
}
}
/* ───────────────────────────────────────────────────────────── */
pub fn decompress_file_to_temp(path: &Path) -> Result<(CompressedContent, TempDir)> {
let temp_dir = tempdir()?;
let content = decompress_file(path, Some(temp_dir.path()))?;
let mut content = decompress_file(path, Some(temp_dir.path()))?;
if let CompressedContent::Archive(ref files) = content {
// if let CompressedContent::Archive(ref files) = content {
let mut prefix_for_replace = None;
if let Some(stem) = path.file_stem() {
let candidate = temp_dir.path().join(stem).with_extension("decomp.tar");
prefix_for_replace = Some(candidate);
}
if let CompressedContent::Archive(ref mut files) = content {
if let Some(prefix) = &prefix_for_replace {
let prefix_str = prefix.display().to_string();
for (name, _) in files.iter_mut() {
if let Some(rest) = name.strip_prefix(&prefix_str) {
if let Some((_, suffix)) = rest.split_once('!') {
*name = format!("{}!{}", path.display(), suffix);
}
}
}
}
for (name, data) in files {
let rel = name.split_once('!').map(|(_, sub)| sub).unwrap_or(name);
let p = temp_dir.path().join(rel.replace('\\', "/"));
@ -270,6 +286,17 @@ pub fn decompress_file_to_temp(path: &Path) -> Result<(CompressedContent, TempDi
}
fs::write(p, data)?;
}
} else if let CompressedContent::ArchiveFiles(ref mut entries) = content {
if let Some(prefix) = &prefix_for_replace {
let prefix_str = prefix.display().to_string();
for (name, _) in entries.iter_mut() {
if let Some(rest) = name.strip_prefix(&prefix_str) {
if let Some((_, suffix)) = rest.split_once('!') {
*name = format!("{}!{}", path.display(), suffix);
}
}
}
}
}
Ok((content, temp_dir))
}

View file

@ -72,6 +72,9 @@ impl Docker {
let digest = format!("{:x}", Sha256::digest(&data));
let new_path = out_dir.join(format!("layer_{digest}.tar"));
std::fs::rename(&p, &new_path)?;
// extract layer contents so inner filenames appear in scan results
decompress_file(&new_path, Some(out_dir))?;
std::fs::remove_file(&new_path)?;
pb.inc(1);
}
@ -131,6 +134,8 @@ impl Docker {
let tmp_path = out_dir.join(file_name);
let mut tmp = std::fs::File::create(&tmp_path)?;
tmp.write_all(&layer.data)?;
decompress_file(&tmp_path, Some(out_dir))?;
std::fs::remove_file(&tmp_path)?;
pb.inc(1);
}
pb.finish_with_message(format!("saved {image}"));

View file

@ -89,7 +89,6 @@ pub async fn run_async_scan(
}
}
if input_roots.is_empty() {
bail!("No inputs to scan");
}