Skip to content

Commit e385fe4

Browse files
committed
ifd: fix Clippy issues, rework parsing
- get rid of unwrap()s - add bounds checks Signed-off-by: Daniel Maslowski <[email protected]>
1 parent e8fb2e0 commit e385fe4

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

src/ifd.rs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -525,12 +525,12 @@ impl Debug for IFD {
525525
}
526526

527527
/// Extract a bit from a given byte, as bool.
528-
fn extract_bit(straps: &Vec<u32>, byte: usize, bit: u32) -> bool {
528+
fn extract_bit(straps: &[u32], byte: usize, bit: u32) -> bool {
529529
straps[byte] >> bit & 1 == 1
530530
}
531531

532532
/// Set or clear a bit in a given strap, identified by its number.
533-
fn set_bit(straps: &mut Vec<u32>, byte: usize, bit: u32, s: bool) {
533+
fn set_bit(straps: &mut [u32], byte: usize, bit: u32, s: bool) {
534534
let b = straps[byte];
535535
straps[byte] = b & !(1 << bit) | ((s as u32) << bit);
536536
}
@@ -684,6 +684,9 @@ const REGION_COUNT: usize = 8;
684684
#[derive(Serialize, Deserialize, Clone, Debug)]
685685
pub enum IfdError {
686686
NoIfd(String),
687+
DataTooSmall(String),
688+
ParserError(String),
689+
OutOfBounds(String),
687690
}
688691

689692
fn u8_slice_to_u32(slice: &[u8]) -> Vec<u32> {
@@ -695,7 +698,15 @@ fn u8_slice_to_u32(slice: &[u8]) -> Vec<u32> {
695698

696699
impl IFD {
697700
pub fn parse(data: &[u8]) -> Result<Self, IfdError> {
698-
let (header, _) = Header::read_from_prefix(&data[OFFSET..]).unwrap();
701+
if data.len() < OFFSET {
702+
return Err(IfdError::DataTooSmall(
703+
"Not enough data: need at least 4096 bytes".into(),
704+
));
705+
}
706+
let header = match Header::read_from_prefix(&data[OFFSET..]) {
707+
Ok((r, _)) => r,
708+
Err(e) => return Err(IfdError::ParserError(format!("IFD header: {e:?}"))),
709+
};
699710

700711
if header.magic != MAGIC {
701712
return Err(IfdError::NoIfd(format!(
@@ -710,17 +721,51 @@ impl IFD {
710721
let pch_straps_offset = header.flmap1.fisba();
711722
let mch_straps_offset = header.flmap2.fmsba();
712723

713-
let (components, _) = Components::read_from_prefix(&data[components_offset..]).unwrap();
714-
715-
let (regions, _) = Regions::read_from_prefix(&data[regions_offset..]).unwrap();
716-
717-
let slice = &data[masters_offset..masters_offset + REGION_COUNT * 4];
724+
if components_offset > data.len() {
725+
return Err(IfdError::OutOfBounds(format!(
726+
"Components @ {components_offset:08x}"
727+
)));
728+
}
729+
let components = match Components::read_from_prefix(&data[components_offset..]) {
730+
Ok((r, _)) => r,
731+
Err(e) => return Err(IfdError::ParserError(format!("{e:?}"))),
732+
};
733+
734+
if regions_offset > data.len() {
735+
return Err(IfdError::OutOfBounds(format!(
736+
"Regions @ {regions_offset:08x}"
737+
)));
738+
}
739+
let regions = match Regions::read_from_prefix(&data[regions_offset..]) {
740+
Ok((r, _)) => r,
741+
Err(e) => return Err(IfdError::ParserError(format!("{e:?}"))),
742+
};
743+
744+
let masters_end = masters_offset + REGION_COUNT * 4;
745+
if masters_offset > data.len() || masters_end > data.len() {
746+
return Err(IfdError::OutOfBounds(format!(
747+
"Masters @ {masters_offset:08x}..{masters_end:08x}"
748+
)));
749+
}
750+
let slice = &data[masters_offset..masters_end];
718751
let masters = u8_slice_to_u32(slice);
719752

720-
let slice = &data[pch_straps_offset..pch_straps_offset + header.flmap1.isl() * 4];
753+
let pch_straps_end = pch_straps_offset + header.flmap1.isl() * 4;
754+
if pch_straps_offset > data.len() || pch_straps_end > data.len() {
755+
return Err(IfdError::OutOfBounds(format!(
756+
"PCH straps @ {pch_straps_offset:08x}..{pch_straps_end:08x}"
757+
)));
758+
}
759+
let slice = &data[pch_straps_offset..pch_straps_end];
721760
let pch_straps = u8_slice_to_u32(slice);
722761

723-
let slice = &data[mch_straps_offset..mch_straps_offset + header.flmap2.msl() * 4];
762+
let mch_straps_end = mch_straps_offset + header.flmap2.msl() * 4;
763+
if mch_straps_offset > data.len() || mch_straps_end > data.len() {
764+
return Err(IfdError::OutOfBounds(format!(
765+
"MCH straps @ {mch_straps_offset:08x}..{mch_straps_end:08x}"
766+
)));
767+
}
768+
let slice = &data[mch_straps_offset..mch_straps_end];
724769
let mch_straps = u8_slice_to_u32(slice);
725770

726771
Ok(Self {

0 commit comments

Comments
 (0)