@@ -23,12 +23,10 @@ pub struct Multiboot2Header<'a> {
2323}
2424
2525impl < ' a > Multiboot2Header < ' a > {
26- /// Public constructor for this type with various validations. It panics if the address is invalid.
27- /// It panics rather than returning a result, because if this fails, it is
28- /// a fatal, unrecoverable error anyways and a bug in your code.
26+ /// Public constructor for this type with various validations.
2927 ///
30- /// # Panics
31- /// Panics if one of the following conditions is true :
28+ /// If the header is invalid, it returns a [`LoadError`].
29+ /// This may be because :
3230 /// - `addr` is a null-pointer
3331 /// - `addr` isn't 8-byte aligned
3432 /// - the magic value of the header is not present
@@ -37,38 +35,31 @@ impl<'a> Multiboot2Header<'a> {
3735 /// # Safety
3836 /// This function may produce undefined behaviour, if the provided `addr` is not a valid
3937 /// Multiboot2 header pointer.
40- pub unsafe fn from_addr ( addr : usize ) -> Self {
41- assert_ne ! ( 0 , addr, "`addr` is null pointer" ) ;
42- assert_eq ! (
43- addr % 8 ,
44- 0 ,
45- "`addr` must be 8-byte aligned, see Multiboot2 spec"
46- ) ;
38+ // This function can be `const` on newer Rust versions.
39+ #[ allow( clippy:: missing_const_for_fn) ]
40+ pub unsafe fn from_addr ( addr : usize ) -> Result < Self , LoadError > {
41+ if addr == 0 || addr % 8 != 0 {
42+ return Err ( LoadError :: InvalidAddress ) ;
43+ }
4744 let ptr = addr as * const Multiboot2BasicHeader ;
4845 let reference = & * ptr;
49- assert_eq ! (
50- reference. header_magic( ) ,
51- MULTIBOOT2_HEADER_MAGIC ,
52- "The Multiboot2 header must contain the MULTIBOOT2_HEADER_MAGIC={:x}" ,
53- MULTIBOOT2_HEADER_MAGIC
54- ) ;
55- assert ! (
56- reference. verify_checksum( ) ,
57- "checksum invalid! Is {:x}, expected {:x}" ,
58- reference. checksum( ) ,
59- Self :: calc_checksum( reference. header_magic, reference. arch, reference. length)
60- ) ;
61- Self { inner : reference }
46+ if reference. header_magic ( ) != MULTIBOOT2_HEADER_MAGIC {
47+ return Err ( LoadError :: MagicNotFound ) ;
48+ }
49+ if !reference. verify_checksum ( ) {
50+ return Err ( LoadError :: ChecksumMismatch ) ;
51+ }
52+ Ok ( Self { inner : reference } )
6253 }
6354
6455 /// Find the header in a given slice.
6556 ///
6657 /// If it succeeds, it returns a tuple consisting of the subslice containing
6758 /// just the header and the index of the header in the given slice.
6859 /// If it fails (either because the header is not properply 64-bit aligned
69- /// or because it is truncated), it returns a [`BufError `].
60+ /// or because it is truncated), it returns a [`LoadError `].
7061 /// If there is no header, it returns `None`.
71- pub fn find_header ( buffer : & [ u8 ] ) -> Result < Option < ( & [ u8 ] , u32 ) > , BufError > {
62+ pub fn find_header ( buffer : & [ u8 ] ) -> Result < Option < ( & [ u8 ] , u32 ) > , LoadError > {
7263 // the magic is 32 bit aligned and inside the first 8192 bytes
7364 assert ! ( buffer. len( ) >= 8192 ) ;
7465 let mut windows = buffer[ 0 ..8192 ] . windows ( 4 ) ;
@@ -80,7 +71,7 @@ impl<'a> Multiboot2Header<'a> {
8071 if idx % 8 == 0 {
8172 idx
8273 } else {
83- return Err ( BufError :: Unaligned ) ;
74+ return Err ( LoadError :: InvalidAddress ) ;
8475 }
8576 }
8677 None => return Ok ( None ) ,
@@ -97,7 +88,7 @@ impl<'a> Multiboot2Header<'a> {
9788 let header_length: usize = u32:: from_le_bytes (
9889 windows
9990 . next ( )
100- . ok_or ( BufError :: TooSmall ) ?
91+ . ok_or ( LoadError :: TooSmall ) ?
10192 . try_into ( )
10293 . unwrap ( ) , // 4 bytes are a u32
10394 )
@@ -210,11 +201,15 @@ impl<'a> Debug for Multiboot2Header<'a> {
210201/// Errors that can occur when parsing a header from a slice.
211202/// See [`Multiboot2Header::find_header`].
212203#[ derive( Debug , Clone , PartialEq , Eq ) ]
213- pub enum BufError {
214- /// The header in the given slice is truncated.
204+ pub enum LoadError {
205+ /// The checksum does not match the data.
206+ ChecksumMismatch ,
207+ /// The header is not properly 64-bit aligned (or a null pointer).
208+ InvalidAddress ,
209+ /// The header does not contain the correct magic number.
210+ MagicNotFound ,
211+ /// The header is truncated.
215212 TooSmall ,
216- /// The header in the given slice is not properly 64-bit aligned.
217- Unaligned ,
218213}
219214
220215/// **Use this only if you know what you do. You probably want to use
0 commit comments