mod builder;
use builder::{
EVF_SIGNATURE, FILE_HEADER_SIZE, SECTION_DESCRIPTOR_SIZE, VOLUME_DATA_SIZE,
make_section_descriptor,
};
use ewf_forensic::{EwfIntegrity, EwfIntegrityAnomaly};
fn e01_without_sectors_or_table() -> Vec<u8> {
let mut buf: Vec<u8> = Vec::new();
buf.extend_from_slice(&EVF_SIGNATURE);
buf.push(0x01); buf.extend_from_slice(&1u16.to_le_bytes()); buf.extend_from_slice(&0u16.to_le_bytes());
let header_section_size = (SECTION_DESCRIPTOR_SIZE + 1) as u64;
let volume_section_size = (SECTION_DESCRIPTOR_SIZE + VOLUME_DATA_SIZE) as u64;
let done_section_size = SECTION_DESCRIPTOR_SIZE as u64;
let base = FILE_HEADER_SIZE as u64;
let volume_off = base + header_section_size;
let done_off = volume_off + volume_section_size;
buf.extend_from_slice(&make_section_descriptor("header", volume_off, header_section_size));
buf.push(0u8);
buf.extend_from_slice(&make_section_descriptor("volume", done_off, volume_section_size));
buf.extend(std::iter::repeat(0u8).take(VOLUME_DATA_SIZE));
buf.extend_from_slice(&make_section_descriptor("done", done_off, done_section_size));
buf
}
fn e01_without_table() -> Vec<u8> {
let sectors_body: Vec<u8> = vec![0u8; 512 * 64];
let mut buf: Vec<u8> = Vec::new();
let header_section_size = (SECTION_DESCRIPTOR_SIZE + 1) as u64;
let volume_section_size = (SECTION_DESCRIPTOR_SIZE + VOLUME_DATA_SIZE) as u64;
let sectors_section_size = SECTION_DESCRIPTOR_SIZE as u64 + sectors_body.len() as u64;
let done_section_size = SECTION_DESCRIPTOR_SIZE as u64;
let base = FILE_HEADER_SIZE as u64;
let volume_off = base + header_section_size;
let sectors_off = volume_off + volume_section_size;
let done_off = sectors_off + sectors_section_size;
buf.extend_from_slice(&EVF_SIGNATURE);
buf.push(0x01);
buf.extend_from_slice(&1u16.to_le_bytes());
buf.extend_from_slice(&0u16.to_le_bytes());
buf.extend_from_slice(&make_section_descriptor("header", volume_off, header_section_size));
buf.push(0u8);
buf.extend_from_slice(&make_section_descriptor("volume", sectors_off, volume_section_size));
buf.extend(std::iter::repeat(0u8).take(VOLUME_DATA_SIZE));
buf.extend_from_slice(&make_section_descriptor("sectors", done_off, sectors_section_size));
buf.extend_from_slice(§ors_body);
buf.extend_from_slice(&make_section_descriptor("done", done_off, done_section_size));
buf
}
#[test]
fn clean_e01_has_no_missing_section_anomalies() {
let image = builder::E01Builder::new(512 * 64).build();
let findings = EwfIntegrity::new(&image).analyse();
assert!(
!findings
.iter()
.any(|a| matches!(a, EwfIntegrityAnomaly::SectorsSectionMissing)),
"clean image must not produce SectorsSectionMissing; got: {findings:#?}"
);
assert!(
!findings
.iter()
.any(|a| matches!(a, EwfIntegrityAnomaly::TableSectionMissing)),
"clean image must not produce TableSectionMissing; got: {findings:#?}"
);
}
#[test]
fn e01_missing_sectors_detected() {
let image = e01_without_sectors_or_table();
let findings = EwfIntegrity::new(&image).analyse();
assert!(
findings
.iter()
.any(|a| matches!(a, EwfIntegrityAnomaly::SectorsSectionMissing)),
"missing sectors section must produce SectorsSectionMissing; got: {findings:#?}"
);
}
#[test]
fn e01_missing_table_detected() {
let image = e01_without_table();
let findings = EwfIntegrity::new(&image).analyse();
assert!(
findings
.iter()
.any(|a| matches!(a, EwfIntegrityAnomaly::TableSectionMissing)),
"missing table section must produce TableSectionMissing; got: {findings:#?}"
);
}