gzip header loading
parent
b5dfcf3ee2
commit
b33dc356c4
|
@ -0,0 +1,62 @@
|
||||||
|
//! DEFLATE loader.
|
||||||
|
|
||||||
|
use crate::durandal::err::*;
|
||||||
|
|
||||||
|
/// Loads a GZIP file header.
|
||||||
|
pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
|
||||||
|
{
|
||||||
|
const FHCRC: u8 = 1 << 1;
|
||||||
|
const FEXTRA: u8 = 1 << 2;
|
||||||
|
const FNAME: u8 = 1 << 3;
|
||||||
|
const FCOMMENT: u8 = 1 << 4;
|
||||||
|
|
||||||
|
read_data! {
|
||||||
|
10, LE in b =>
|
||||||
|
id = u16[0];
|
||||||
|
cm = u8[2];
|
||||||
|
fl = u8[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if id != 0x8B1F || cm != 8 {
|
||||||
|
bail!("not gzip format");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut p = 10;
|
||||||
|
|
||||||
|
if fl & FEXTRA != 0 {
|
||||||
|
read_data!(p + 2, LE in b => xlen = u16[p] usize;);
|
||||||
|
|
||||||
|
if p + 2 + xlen > b.len() {
|
||||||
|
bail!("not enough data");
|
||||||
|
}
|
||||||
|
|
||||||
|
p += xlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if fl & FNAME != 0 {
|
||||||
|
p = skip_zero_terminated_item(&b[p..])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if fl & FCOMMENT != 0 {
|
||||||
|
p = skip_zero_terminated_item(&b[p..])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if fl & FHCRC != 0 {
|
||||||
|
read_data!(p + 2, LE in b => _crc = u16[p];);
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_zero_terminated_item(b: &[u8]) -> ResultS<usize>
|
||||||
|
{
|
||||||
|
if let Some(i) = b.iter().position(|&n| n == 0) {
|
||||||
|
Ok(i)
|
||||||
|
} else {
|
||||||
|
bail!("no end of zero terminated item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -1,5 +1,6 @@
|
||||||
//! Library for file format data readers.
|
//! Library for file format data readers.
|
||||||
|
|
||||||
|
pub mod defl;
|
||||||
pub mod machdr;
|
pub mod machdr;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod phy;
|
pub mod phy;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,29 @@
|
||||||
|
use maraiah::marathon::defl::{self, load_gzip_header};
|
||||||
|
|
||||||
|
include!("data/rand.rs");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn defl_must_succeed()
|
||||||
|
{
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipok1.bin")).is_ok());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipok2.bin")).is_ok());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipok3.bin")).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn defl_must_not_succeed()
|
||||||
|
{
|
||||||
|
for inp in &RANDOM {
|
||||||
|
assert!(defl::load_gzip_header(inp).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad1.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad2.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad3.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad4.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad5.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad6.bin")).is_err());
|
||||||
|
assert!(load_gzip_header(include_bytes!("data/gzipbad7.bin")).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
Loading…
Reference in New Issue