Skip to content

Commit 9d01724

Browse files
Merge pull request #1197 from andre-braga/node
uefi: Add TryFrom u8 slice to DevicePathNode
2 parents 99a2433 + 8c61286 commit 9d01724

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

uefi/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
- Added `table::{set_system_table, system_table_boot, system_table_runtime}`.
1212
This provides an initial API for global tables that do not require passing
1313
around a reference.
14-
- Added `TryFrom<&[u8]>` for `DevicePathHeader`.
14+
- Added `TryFrom<&[u8]>` for `DevicePathHeader` and `DevicePathNode`.
1515
- Added `ByteConversionError`.
1616

1717
## Changed

uefi/src/proto/device_path/mod.rs

+42
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,19 @@ impl PartialEq for DevicePathNode {
266266
}
267267
}
268268

269+
impl<'a> TryFrom<&[u8]> for &'a DevicePathNode {
270+
type Error = ByteConversionError;
271+
272+
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
273+
let dp = <&DevicePathHeader>::try_from(bytes)?;
274+
if usize::from(dp.length) <= bytes.len() {
275+
unsafe { Ok(DevicePathNode::from_ffi_ptr(bytes.as_ptr().cast())) }
276+
} else {
277+
Err(ByteConversionError::InvalidLength)
278+
}
279+
}
280+
}
281+
269282
/// A single device path instance that ends with either an [`END_INSTANCE`]
270283
/// or [`END_ENTIRE`] node. Use [`DevicePath::instance_iter`] to get the
271284
/// path instances in a [`DevicePath`].
@@ -975,4 +988,33 @@ mod tests {
975988
let owned_dp_ref = &*owned_dp;
976989
assert_eq!(owned_dp_ref, dp)
977990
}
991+
992+
#[test]
993+
fn test_device_path_node_from_bytes() {
994+
let mut raw_data = Vec::new();
995+
let node = [0xa0, 0xb0];
996+
let node_data = &[10, 11];
997+
998+
// Raw data is less than size of a [`DevicePathNode`].
999+
raw_data.push(node[0]);
1000+
assert!(<&DevicePathNode>::try_from(raw_data.as_slice()).is_err());
1001+
1002+
// Raw data is long enough to hold a [`DevicePathNode`].
1003+
raw_data.push(node[1]);
1004+
raw_data.extend(
1005+
u16::try_from(mem::size_of::<DevicePathHeader>() + node_data.len())
1006+
.unwrap()
1007+
.to_le_bytes(),
1008+
);
1009+
raw_data.extend(node_data);
1010+
let dp = <&DevicePathNode>::try_from(raw_data.as_slice()).unwrap();
1011+
1012+
// Relevant assertions to verify the conversion is fine.
1013+
assert_eq!(mem::size_of_val(dp), 6);
1014+
check_node(dp, 0xa0, 0xb0, &[10, 11]);
1015+
1016+
// [`DevicePathNode`] data length exceeds the raw_data slice.
1017+
raw_data[2] += 1;
1018+
assert!(<&DevicePathNode>::try_from(raw_data.as_slice()).is_err());
1019+
}
9781020
}

0 commit comments

Comments
 (0)