@@ -253,6 +253,23 @@ impl PartialEq for DevicePathNode {
253
253
}
254
254
}
255
255
256
+ impl < ' a > TryFrom < & [ u8 ] > for & ' a DevicePathNode {
257
+ type Error = ByteConversionError ;
258
+
259
+ fn try_from ( bytes : & [ u8 ] ) -> Result < Self , Self :: Error > {
260
+ if mem:: size_of :: < DevicePathHeader > ( ) <= bytes. len ( ) {
261
+ let dp: & DevicePathNode ;
262
+ unsafe {
263
+ dp = DevicePathNode :: from_ffi_ptr ( bytes. as_ptr ( ) . cast ( ) ) ;
264
+ }
265
+ if dp. length ( ) as usize <= bytes. len ( ) {
266
+ return Ok ( dp) ;
267
+ }
268
+ }
269
+ Err ( ByteConversionError :: InvalidLength )
270
+ }
271
+ }
272
+
256
273
/// A single device path instance that ends with either an [`END_INSTANCE`]
257
274
/// or [`END_ENTIRE`] node. Use [`DevicePath::instance_iter`] to get the
258
275
/// path instances in a [`DevicePath`].
@@ -729,6 +746,15 @@ impl DeviceSubType {
729
746
pub const END_ENTIRE : DeviceSubType = DeviceSubType ( 0xff ) ;
730
747
}
731
748
749
+ /// Error returned when atempting to convert from a `&[u8]` to a
750
+ /// [`DevicePath`] type using:
751
+ /// - [`DevicePathNode::try_from`](struct.DevicePathNode.html#method.try_from)
752
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
753
+ pub enum ByteConversionError {
754
+ /// The length of the given slice is not valid for its [`DevicePath`] type.
755
+ InvalidLength ,
756
+ }
757
+
732
758
/// Error returned when converting from a [`DevicePathNode`] to a more
733
759
/// specific node type.
734
760
#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
@@ -954,4 +980,33 @@ mod tests {
954
980
let owned_dp_ref = & * owned_dp;
955
981
assert_eq ! ( owned_dp_ref, dp)
956
982
}
983
+
984
+ #[ test]
985
+ fn test_device_path_from_bytes ( ) {
986
+ let mut raw_data = Vec :: new ( ) ;
987
+ let node = [ 0xa0 , 0xb0 ] ;
988
+ let node_data = & [ 10 , 11 ] ;
989
+ let mut dp;
990
+
991
+ // Raw data is less than size of a [`DevicePathNode`].
992
+ raw_data. push ( node[ 0 ] ) ;
993
+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
994
+ assert ! ( dp. is_err( ) ) ;
995
+
996
+ // Raw data is long enough to hold a [`DevicePathNode`].
997
+ raw_data. push ( node[ 1 ] ) ;
998
+ raw_data. extend (
999
+ u16:: try_from ( mem:: size_of :: < DevicePathHeader > ( ) + node_data. len ( ) )
1000
+ . unwrap ( )
1001
+ . to_le_bytes ( ) ,
1002
+ ) ;
1003
+ raw_data. extend ( node_data) ;
1004
+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
1005
+ assert ! ( dp. is_ok( ) ) ;
1006
+
1007
+ // [`DevicePathNode`] data length exceeds the raw_data slice.
1008
+ raw_data[ 2 ] += 1 ;
1009
+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
1010
+ assert ! ( dp. is_err( ) ) ;
1011
+ }
957
1012
}
0 commit comments