Skip to main content

assay_sim/mutators/
inject.rs

1use super::Mutator;
2use anyhow::Result;
3use std::io::Cursor;
4
5pub struct InjectFile {
6    pub name: String,
7    pub content: Vec<u8>,
8}
9
10impl Mutator for InjectFile {
11    fn mutate(&self, data: &[u8]) -> Result<Vec<u8>> {
12        // 1. Decode existing
13        let mut archive = tar::Archive::new(flate2::read::GzDecoder::new(Cursor::new(data)));
14
15        // 2. Rebuild with injection
16        let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
17        {
18            let mut builder = tar::Builder::new(&mut encoder);
19
20            // Copy existing
21            for entry in archive.entries()? {
22                let mut entry = entry?;
23                let mut entry_content = Vec::new();
24                std::io::Read::read_to_end(&mut entry, &mut entry_content)?;
25
26                let header = entry.header().clone();
27                builder.append(&header, entry_content.as_slice())?;
28            }
29
30            // Inject new
31            let mut header = tar::Header::new_gnu();
32            header.set_path(&self.name)?;
33            header.set_size(self.content.len() as u64);
34            header.set_mode(0o644);
35            header.set_cksum();
36            builder.append(&header, self.content.as_slice())?;
37
38            builder.finish()?;
39        }
40        Ok(encoder.finish()?)
41    }
42}