threatflux_binary_analysis/utils/
compression.rs1use crate::{error::BinaryError, Result};
2use flate2::read::{GzDecoder, ZlibDecoder};
3use std::io::Read;
4
5#[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}