Skip to content

Commit

Permalink
Merge pull request #98 from sorairolake/feature/archives
Browse files Browse the repository at this point in the history
Add bzip3 and LZ4 support
  • Loading branch information
bojand authored Feb 2, 2025
2 parents 644cf90 + f591327 commit cbf3b9e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ assert_eq!(kind.extension(), "foo");
- **rar** - `application/vnd.rar`
- **gz** - `application/gzip`
- **bz2** - `application/x-bzip2`
- **bz3** - `application/vnd.bzip3`
- **7z** - `application/x-7z-compressed`
- **xz** - `application/x-xz`
- **pdf** - `application/pdf`
Expand All @@ -175,6 +176,7 @@ assert_eq!(kind.extension(), "foo");
- **rpm** - `application/x-rpm`
- **dcm** - `application/dicom`
- **zst** - `application/zstd`
- **lz4** - `application/x-lz4`
- **msi** - `application/x-ole-storage`
- **cpio** - `application/x-cpio`

Expand Down
12 changes: 12 additions & 0 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@ matcher_map!(
"bz2",
matchers::archive::is_bz2
),
(
MatcherType::Archive,
"application/vnd.bzip3",
"bz3",
matchers::archive::is_bz3
),
(
MatcherType::Archive,
"application/x-7z-compressed",
Expand Down Expand Up @@ -570,6 +576,12 @@ matcher_map!(
"zst",
matchers::archive::is_zst
),
(
MatcherType::Archive,
"application/x-lz4",
"lz4",
matchers::archive::is_lz4
),
(
MatcherType::Archive,
"application/x-ole-storage",
Expand Down
47 changes: 46 additions & 1 deletion src/matchers/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,21 @@ pub fn is_gz(buf: &[u8]) -> bool {
buf.len() > 2 && buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x8
}

/// Returns whether a buffer is a bzip archive.
/// Returns whether a buffer is a bzip2 archive.
pub fn is_bz2(buf: &[u8]) -> bool {
buf.len() > 2 && buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68
}

/// Returns whether a buffer is a bzip3 archive.
pub fn is_bz3(buf: &[u8]) -> bool {
buf.len() > 4
&& buf[0] == b'B'
&& buf[1] == b'Z'
&& buf[2] == b'3'
&& buf[3] == b'v'
&& buf[4] == b'1'
}

/// Returns whether a buffer is a 7z archive.
pub fn is_7z(buf: &[u8]) -> bool {
buf.len() > 5
Expand Down Expand Up @@ -239,6 +249,41 @@ pub fn is_zst(buf: &[u8]) -> bool {
is_zst(next_frame)
}

/// Returns whether a buffer is a LZ4 archive.
// LZ4 compressed data is made of one or more frames.
// There are two frame formats defined by LZ4: LZ4 Frame format and Skippable frames.
// See more details from https://github.com/lz4/lz4/blob/v1.9.4/doc/lz4_Frame_format.md
pub fn is_lz4(buf: &[u8]) -> bool {
if buf.len() > 3 && buf[0] == 0x04 && buf[1] == 0x22 && buf[2] == 0x4D && buf[3] == 0x18 {
return true;
}

if buf.len() < 8 {
return false;
}

let magic = u32::from_le_bytes(buf[0..4].try_into().unwrap());
let Ok(magic) = usize::try_from(magic) else {
return false;
};

if magic & ZSTD_SKIP_MASK != ZSTD_SKIP_START {
return false;
}

let data_len = u32::from_le_bytes(buf[4..8].try_into().unwrap());
let Ok(data_len) = usize::try_from(data_len) else {
return false;
};

if buf.len() < 8 + data_len {
return false;
}

let next_frame = &buf[8 + data_len..];
is_lz4(next_frame)
}

/// Returns whether a buffer is a MSI Windows Installer archive.
pub fn is_msi(buf: &[u8]) -> bool {
buf.len() > 7
Expand Down
Binary file added testdata/sample.tar.bz3
Binary file not shown.
Binary file added testdata/sample.tar.lz4
Binary file not shown.
8 changes: 8 additions & 0 deletions tests/archive.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
mod common;

test_format!(
Archive,
"application/vnd.bzip3",
"bz3",
bz3,
"sample.tar.bz3"
);
test_format!(
Archive,
"application/vnd.sqlite3",
Expand All @@ -9,6 +16,7 @@ test_format!(
);

test_format!(Archive, "application/zstd", "zst", zst, "sample.tar.zst");
test_format!(Archive, "application/x-lz4", "lz4", lz4, "sample.tar.lz4");
test_format!(Archive, "application/x-cpio", "cpio", cpio, "sample.cpio");
test_format!(
Archive,
Expand Down

0 comments on commit cbf3b9e

Please sign in to comment.