diff --git a/src/decompress.rs b/src/decompress.rs index 88a11ae..8bc43aa 100644 --- a/src/decompress.rs +++ b/src/decompress.rs @@ -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)) } diff --git a/src/scanner/docker.rs b/src/scanner/docker.rs index 4a61ac3..f6e16ed 100644 --- a/src/scanner/docker.rs +++ b/src/scanner/docker.rs @@ -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}")); diff --git a/src/scanner/runner.rs b/src/scanner/runner.rs index 52c8004..f1271cf 100644 --- a/src/scanner/runner.rs +++ b/src/scanner/runner.rs @@ -89,7 +89,6 @@ pub async fn run_async_scan( } } - if input_roots.is_empty() { bail!("No inputs to scan"); }