gzip header loading

png-branch
an 2019-03-09 17:07:18 -05:00
parent b5dfcf3ee2
commit b33dc356c4
13 changed files with 92 additions and 0 deletions

62
source/marathon/defl.rs Normal file
View File

@ -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

View File

@ -1,5 +1,6 @@
//! Library for file format data readers.
pub mod defl;
pub mod machdr;
pub mod map;
pub mod phy;

BIN
tests/data/gzipbad1.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad2.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad3.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad4.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad5.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad6.bin Normal file

Binary file not shown.

BIN
tests/data/gzipbad7.bin Normal file

Binary file not shown.

BIN
tests/data/gzipok1.bin Normal file

Binary file not shown.

BIN
tests/data/gzipok2.bin Normal file

Binary file not shown.

BIN
tests/data/gzipok3.bin Normal file

Binary file not shown.

29
tests/defl.rs Normal file
View File

@ -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