threatflux_binary_analysis/utils/
compression.rs

1use crate::{error::BinaryError, Result};
2use flate2::read::{GzDecoder, ZlibDecoder};
3use std::io::Read;
4
5/// Decompress gzip or zlib data.
6#[cfg(feature = "compression")]
7pub fn decompress(data: &[u8]) -> Result<Vec<u8>> {
8    if data.starts_with(b"\x1f\x8b") {
9        let mut decoder = GzDecoder::new(data);
10        let mut out = Vec::new();
11        decoder.read_to_end(&mut out)?;
12        Ok(out)
13    } else if data.starts_with(b"\x78\x9c")
14        || data.starts_with(b"\x78\x01")
15        || data.starts_with(b"\x78\xda")
16    {
17        let mut decoder = ZlibDecoder::new(data);
18        let mut out = Vec::new();
19        decoder.read_to_end(&mut out)?;
20        Ok(out)
21    } else {
22        Err(BinaryError::invalid_data("unsupported compression format"))
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use flate2::write::{GzEncoder, ZlibEncoder};
30    use flate2::Compression;
31
32    #[cfg(feature = "compression")]
33    #[test]
34    fn test_decompress_gzip() {
35        let data = b"hello world";
36        let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
37        use std::io::Write;
38        encoder.write_all(data).unwrap();
39        let compressed = encoder.finish().unwrap();
40
41        let decompressed = decompress(&compressed).unwrap();
42        assert_eq!(decompressed, data);
43    }
44
45    #[cfg(feature = "compression")]
46    #[test]
47    fn test_decompress_zlib() {
48        let data = b"another test";
49        let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
50        use std::io::Write;
51        encoder.write_all(data).unwrap();
52        let compressed = encoder.finish().unwrap();
53
54        let decompressed = decompress(&compressed).unwrap();
55        assert_eq!(decompressed, data);
56    }
57}