@@ -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 ) ]
685685pub enum IfdError {
686686 NoIfd ( String ) ,
687+ DataTooSmall ( String ) ,
688+ ParserError ( String ) ,
689+ OutOfBounds ( String ) ,
687690}
688691
689692fn u8_slice_to_u32 ( slice : & [ u8 ] ) -> Vec < u32 > {
@@ -695,7 +698,15 @@ fn u8_slice_to_u32(slice: &[u8]) -> Vec<u32> {
695698
696699impl 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