Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
`BootServices::open_protocol`) instead.
- renamed feature `ignore-logger-errors` to `panic-on-logger-errors` so that it is
additive. It is now a default feature.
- The library doesn't longer expose the `CStr8` type. It was not relevant in the
API so far, and internally it was replaced by `core::ffi::CStr`. (Since Rust 1.62)

### Removed

Expand Down
51 changes: 0 additions & 51 deletions src/data_types/chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,6 @@ use core::fmt;
#[derive(Clone, Copy, Debug)]
pub struct CharConversionError;

/// A Latin-1 character
#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Char8(u8);

impl TryFrom<char> for Char8 {
type Error = CharConversionError;

fn try_from(value: char) -> Result<Self, Self::Error> {
let code_point = value as u32;
if code_point <= 0xff {
Ok(Char8(code_point as u8))
} else {
Err(CharConversionError)
}
}
}

impl From<Char8> for char {
fn from(char: Char8) -> char {
char.0 as char
}
}

impl From<u8> for Char8 {
fn from(value: u8) -> Self {
Char8(value)
}
}

impl From<Char8> for u8 {
fn from(char: Char8) -> u8 {
char.0
}
}

impl fmt::Debug for Char8 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<char as fmt::Debug>::fmt(&From::from(self.0), f)
}
}

impl fmt::Display for Char8 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<char as fmt::Display>::fmt(&From::from(self.0), f)
}
}

/// Latin-1 version of the NUL character
pub const NUL_8: Char8 = Char8(0);

/// An UCS-2 code point
#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
#[repr(transparent)]
Expand Down
5 changes: 3 additions & 2 deletions src/data_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ pub use self::guid::Guid;
pub use self::guid::{unsafe_guid, Identify};

pub mod chars;
pub use self::chars::{Char16, Char8};
pub use self::chars::Char16;

#[macro_use]
mod enums;

mod strs;

pub use self::strs::{
CStr16, CStr8, EqStrUntilNul, FromSliceWithNulError, FromStrWithBufError, UnalignedCStr16,
CStr16, EqStrUntilNul, FromSliceWithNulError, FromStrWithBufError, UnalignedCStr16,
UnalignedCStr16Error,
};

Expand Down
66 changes: 1 addition & 65 deletions src/data_types/strs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::chars::{Char16, Char8, NUL_16, NUL_8};
use super::chars::{Char16, NUL_16};
use core::fmt;
use core::iter::Iterator;
use core::marker::PhantomData;
Expand Down Expand Up @@ -52,70 +52,6 @@ pub enum FromStrWithBufError {
BufferTooSmall,
}

/// A Latin-1 null-terminated string
///
/// This type is largely inspired by `std::ffi::CStr`, see the documentation of
/// `CStr` for more details on its semantics.
#[repr(transparent)]
pub struct CStr8([Char8]);

impl CStr8 {
/// Wraps a raw UEFI string with a safe C string wrapper
///
/// # Safety
///
/// The function will start accessing memory from `ptr` until the first
/// null byte. It's the callers responsability to ensure `ptr` points to
/// a valid string, in accessible memory.
pub unsafe fn from_ptr<'ptr>(ptr: *const Char8) -> &'ptr Self {
let mut len = 0;
while *ptr.add(len) != NUL_8 {
len += 1
}
let ptr = ptr.cast::<u8>();
Self::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len + 1))
}

/// Creates a C string wrapper from bytes
pub fn from_bytes_with_nul(chars: &[u8]) -> Result<&Self, FromSliceWithNulError> {
let nul_pos = chars.iter().position(|&c| c == 0);
if let Some(nul_pos) = nul_pos {
if nul_pos + 1 != chars.len() {
return Err(FromSliceWithNulError::InteriorNul(nul_pos));
}
Ok(unsafe { Self::from_bytes_with_nul_unchecked(chars) })
} else {
Err(FromSliceWithNulError::NotNulTerminated)
}
}

/// Unsafely creates a C string wrapper from bytes
///
/// # Safety
///
/// It's the callers responsability to ensure chars is a valid Latin-1
/// null-terminated string, with no interior null bytes.
pub unsafe fn from_bytes_with_nul_unchecked(chars: &[u8]) -> &Self {
&*(chars as *const [u8] as *const Self)
}

/// Returns the inner pointer to this C string
pub fn as_ptr(&self) -> *const Char8 {
self.0.as_ptr()
}

/// Converts this C string to a slice of bytes
pub fn to_bytes(&self) -> &[u8] {
let chars = self.to_bytes_with_nul();
&chars[..chars.len() - 1]
}

/// Converts this C string to a slice of bytes containing the trailing 0 char
pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { &*(&self.0 as *const [Char8] as *const [u8]) }
}
}

/// An UCS-2 null-terminated string
///
/// This type is largely inspired by `std::ffi::CStr`, see the documentation of
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub mod data_types;
#[cfg(feature = "exts")]
pub use self::data_types::CString16;
pub use self::data_types::{unsafe_guid, Identify};
pub use self::data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle};
pub use self::data_types::{CStr16, Char16, Event, Guid, Handle};

mod result;
pub use self::result::{Error, Result, ResultExt, Status};
Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ pub use crate::table::runtime::RuntimeServices;
pub use crate::table::{Boot, SystemTable};

// Import the macro for creating the custom entry point, as well as the cstr macros.
pub use uefi_macros::{cstr16, cstr8, entry};
pub use uefi_macros::{cstr16, entry};
5 changes: 3 additions & 2 deletions src/proto/network/pxe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use core::{
use bitflags::bitflags;
use uefi_macros::{unsafe_guid, Protocol};

use crate::{CStr8, Char8, Result, Status};
use crate::{Result, Status};
use core::ffi::{c_char, CStr as CStr8};

use super::{IpAddress, MacAddress};

Expand Down Expand Up @@ -38,7 +39,7 @@ pub struct BaseCode {
buffer_size: &mut u64,
block_size: Option<&usize>,
server_ip: &IpAddress,
filename: *const Char8,
filename: *const c_char,
info: Option<&MtftpInfo>,
dont_use_buffer: bool,
) -> Status,
Expand Down
27 changes: 0 additions & 27 deletions uefi-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,33 +289,6 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
result.into()
}

/// Builds a `CStr8` literal at compile time from a string literal.
///
/// This will throw a compile error if an invalid character is in the passed string.
///
/// # Example
/// ```
/// # use uefi_macros::cstr8;
/// assert_eq!(cstr8!("test").to_bytes_with_nul(), [116, 101, 115, 116, 0]);
/// ```
#[proc_macro]
pub fn cstr8(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input: LitStr = parse_macro_input!(input);
let input = input.value();
match input
.chars()
.map(u8::try_from)
.collect::<Result<Vec<u8>, _>>()
{
Ok(c) => {
quote!(unsafe { ::uefi::CStr8::from_bytes_with_nul_unchecked(&[ #(#c),* , 0 ]) }).into()
}
Err(_) => syn::Error::new_spanned(input, "invalid character in string")
.into_compile_error()
.into(),
}
}

/// Builds a `CStr16` literal at compile time from a string literal.
///
/// This will throw a compile error if an invalid character is in the passed string.
Expand Down
4 changes: 3 additions & 1 deletion uefi-test-runner/src/proto/network.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use core::ffi::CStr as CStr8;
use uefi::{
prelude::BootServices,
proto::network::{
pxe::{BaseCode, DhcpV4Packet, IpFilter, IpFilters, UdpOpFlags},
IpAddress,
},
CStr8,
table::boot::{OpenProtocolAttributes, OpenProtocolParams},
Handle,
};

pub fn test(bt: &BootServices) {
Expand Down