Skip to content

Commit

Permalink
Merge pull request #88 from marcospb19/enhance_zstd_v2
Browse files Browse the repository at this point in the history
enhance: add supposer for zstd skippable frames (v2)
  • Loading branch information
bojand authored Jun 22, 2023
2 parents 3c78fcf + 8c8c835 commit 97a4bd3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
37 changes: 36 additions & 1 deletion src/matchers/archive.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::convert::{TryFrom, TryInto};

/// Returns whether a buffer is an ePub.
pub fn is_epub(buf: &[u8]) -> bool {
crate::book::is_epub(buf)
Expand Down Expand Up @@ -199,9 +201,42 @@ pub fn is_dcm(buf: &[u8]) -> bool {
buf.len() > 131 && buf[128] == 0x44 && buf[129] == 0x49 && buf[130] == 0x43 && buf[131] == 0x4D
}

const ZSTD_SKIP_START: usize = 0x184D2A50;
const ZSTD_SKIP_MASK: usize = 0xFFFFFFF0;

/// Returns whether a buffer is a Zstd archive.
// Zstandard compressed data is made of one or more frames.
// There are two frame formats defined by Zstandard: Zstandard frames and Skippable frames.
// See more details from https://tools.ietf.org/id/draft-kucherawy-dispatch-zstd-00.html#rfc.section.2
pub fn is_zst(buf: &[u8]) -> bool {
buf.len() > 3 && buf[0] == 0x28 && buf[1] == 0xB5 && buf[2] == 0x2F && buf[3] == 0xFD
if buf.len() > 3 && buf[0] == 0x28 && buf[1] == 0xB5 && buf[2] == 0x2F && buf[3] == 0xFD {
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_zst(next_frame)
}

/// Returns whether a buffer is a MSI Windows Installer archive.
Expand Down
Binary file added testdata/sample.skippable.zst
Binary file not shown.
8 changes: 7 additions & 1 deletion tests/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ test_format!(
);

test_format!(Archive, "application/zstd", "zst", zst, "sample.tar.zst");

test_format!(Archive, "application/x-cpio", "cpio", cpio, "sample.cpio");
test_format!(
Archive,
"application/zstd",
"zst",
zst_skip,
"sample.skippable.zst"
);

0 comments on commit 97a4bd3

Please sign in to comment.