pub enum Body {
Bytes(&'static [u8]),
Pattern {
len: usize,
modulus: u8,
},
}
impl Body {
pub fn bytes(&self) -> Vec<u8> {
match self {
Body::Bytes(b) => b.to_vec(),
Body::Pattern { len, modulus } => (0..*len)
.map(|i| (i % usize::from(*modulus)) as u8)
.collect(),
}
}
}
pub struct Member {
pub name: &'static str,
pub method: u16,
pub descriptor: bool,
pub body: Body,
}
pub struct Fixture {
pub file: &'static str,
pub why: &'static str,
pub members: &'static [Member],
}
pub const FIXTURES: &[Fixture] = &[
Fixture {
file: "stored.zip",
why: "two stored (method 0) members: short literal text and a 3 000-byte pattern",
members: &[
Member {
name: "a.txt",
method: 0,
descriptor: false,
body: Body::Bytes(b"stored payload, no compression at all"),
},
Member {
name: "b.bin",
method: 0,
descriptor: false,
body: Body::Pattern {
len: 3000,
modulus: 251,
},
},
],
},
Fixture {
file: "deflated.zip",
why: "deflated (method 8) members: one small, one spanning two stored DEFLATE blocks",
members: &[
Member {
name: "s.txt",
method: 8,
descriptor: false,
body: Body::Bytes(b"deflated payload, compressed with stored DEFLATE blocks"),
},
Member {
name: "big.bin",
method: 8,
descriptor: false,
body: Body::Pattern {
len: 70_000,
modulus: 253,
},
},
],
},
Fixture {
file: "descriptor.zip",
why: "flags-bit-3 members whose CRC and sizes trail the payload, with and without the optional 0x08074b50 signature",
members: &[
Member {
name: "d1.bin",
method: 8,
descriptor: true,
body: Body::Bytes(b"descriptor-backed deflate entry, signed descriptor"),
},
Member {
name: "d2.bin",
method: 8,
descriptor: true,
body: Body::Bytes(b"descriptor-backed deflate entry, unsigned descriptor"),
},
],
},
Fixture {
file: "mixed.zip",
why: "stored, deflated and descriptor-backed members in one directory",
members: &[
Member {
name: "m0.txt",
method: 0,
descriptor: false,
body: Body::Bytes(b"mixed archive member zero, stored"),
},
Member {
name: "m1.bin",
method: 8,
descriptor: false,
body: Body::Pattern {
len: 1500,
modulus: 241,
},
},
Member {
name: "m2.bin",
method: 8,
descriptor: true,
body: Body::Bytes(b"mixed archive member two, behind a signed descriptor"),
},
],
},
Fixture {
file: "comment.zip",
why: "a 100-byte EOCD comment containing a PK\\x05\\x06 lookalike the scanner must skip",
members: &[Member {
name: "a.txt",
method: 0,
descriptor: false,
body: Body::Bytes(b"with comment"),
}],
},
Fixture {
file: "empty.zip",
why: "an archive with no members at all",
members: &[],
},
];