mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 15:20:17 +00:00
fix(utils): improve safety of media loader and utf-16 handling
This commit is contained in:
15
src/utils.rs
15
src/utils.rs
@@ -280,11 +280,14 @@ pub fn utf16_bytes_to_cstring16(bytes: &[u8]) -> Result<CString16> {
|
|||||||
bail!("utf16 bytes must be a multiple of 2");
|
bail!("utf16 bytes must be a multiple of 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: reinterpret &[u8] as &[u16].
|
// Convert the bytes to UTF-16 data.
|
||||||
// We just validated it has the right length.
|
let data = bytes
|
||||||
let ptr = bytes.as_ptr() as *const u16;
|
// Chunk everything into two bytes.
|
||||||
let len = bytes.len() / 2;
|
.chunks_exact(2)
|
||||||
let utf16 = unsafe { std::slice::from_raw_parts(ptr, len) };
|
// Reinterpret the bytes as u16 little-endian.
|
||||||
|
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
||||||
|
// Collect the result into a vector.
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
CString16::try_from(utf16.to_vec()).context("unable to convert utf16 bytes to CString16")
|
CString16::try_from(data).context("unable to convert utf16 bytes to CString16")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ struct MediaLoaderProtocol {
|
|||||||
/// You MUST call [MediaLoaderHandle::unregister] when ready to unregister.
|
/// You MUST call [MediaLoaderHandle::unregister] when ready to unregister.
|
||||||
/// [Drop] is not implemented for this type.
|
/// [Drop] is not implemented for this type.
|
||||||
pub struct MediaLoaderHandle {
|
pub struct MediaLoaderHandle {
|
||||||
/// The vendor GUID of the media loader.
|
|
||||||
guid: Guid,
|
|
||||||
/// The handle of the media loader in the UEFI stack.
|
/// The handle of the media loader in the UEFI stack.
|
||||||
handle: Handle,
|
handle: Handle,
|
||||||
/// The protocol interface pointer.
|
/// The protocol interface pointer.
|
||||||
@@ -229,7 +227,6 @@ impl MediaLoaderHandle {
|
|||||||
|
|
||||||
// Return a handle to the media loader.
|
// Return a handle to the media loader.
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
guid,
|
|
||||||
handle: primary_handle,
|
handle: primary_handle,
|
||||||
protocol,
|
protocol,
|
||||||
path,
|
path,
|
||||||
@@ -239,13 +236,8 @@ impl MediaLoaderHandle {
|
|||||||
/// Unregisters a media loader from the UEFI stack.
|
/// Unregisters a media loader from the UEFI stack.
|
||||||
/// This will free the memory allocated by the passed data.
|
/// This will free the memory allocated by the passed data.
|
||||||
pub fn unregister(self) -> Result<()> {
|
pub fn unregister(self) -> Result<()> {
|
||||||
// Check if the media loader is registered.
|
// SAFETY: We know that the media loader is registered if the handle is valid,
|
||||||
// If it is not, we don't need to do anything.
|
// so we can safely uninstall it.
|
||||||
if !Self::already_registered(self.guid)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// SAFETY: We know that the media loader is registered, so we can safely uninstall it.
|
|
||||||
// We should have allocated the pointers involved, so we can safely free them.
|
// We should have allocated the pointers involved, so we can safely free them.
|
||||||
unsafe {
|
unsafe {
|
||||||
// Uninstall the protocol interface for the device path protocol.
|
// Uninstall the protocol interface for the device path protocol.
|
||||||
|
|||||||
Reference in New Issue
Block a user