Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a96a03f

Browse files
committed
cstr16: add from_u8_with_nul
1 parent 4ace935 commit a96a03f

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- Added `BootServices::install_configuration_table`.
88
- Added `DevicePath::data()`.
9+
- Added `CStr16::from_u8_with_nul`.
910

1011
### Changed
1112

‎uefi-test-runner/src/boot/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fn test_load_image(bt: &BootServices) {
6363
node.device_type() == DeviceType::MEDIA /* 0x4 */
6464
&& node.sub_type() == DeviceSubType::HARDWARE_VENDOR /* 0x4 */
6565
})
66-
.map(|node| unsafe{CStr16::from_ptr(node.data().as_ptr().cast())})
66+
.map(|node| CStr16::from_u8_with_nul(node.data()).expect("should be valid CCtr16"))
6767
// to Rust string
6868
.map(|cstr16| cstr16.to_string().to_uppercase())
6969
.expect("should have file-path portion in device path");

‎uefi/src/data_types/strs.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub enum FromSliceWithNulError {
2222

2323
/// The slice was not null-terminated
2424
NotNulTerminated,
25+
26+
/// The buffer is broken. For example, not a multiple of 2 bytes.
27+
BrokenBuffer,
2528
}
2629

2730
/// Error returned by [`CStr16::from_unaligned_slice`].
@@ -211,10 +214,21 @@ impl CStr16 {
211214
Self::from_u16_with_nul_unchecked(slice::from_raw_parts(ptr, len + 1))
212215
}
213216

214-
/// Creates a C string wrapper from a u16 slice
215-
///
216-
/// Since not every u16 value is a valid UCS-2 code point, this function
217-
/// must do a bit more validity checking than CStr::from_bytes_with_nul
217+
/// Creates a `&CStr16` from a u8 slice, if the slice contains exactly
218+
/// one terminating null-byte and all chars are valid UCS-2 chars.
219+
pub fn from_u8_with_nul(slice: &[u8]) -> Result<&Self, FromSliceWithNulError> {
220+
if slice.is_empty() {
221+
return Err(FromSliceWithNulError::NotNulTerminated);
222+
}
223+
if slice.len() % 2 != 0 {
224+
return Err(FromSliceWithNulError::BrokenBuffer);
225+
}
226+
let slice = unsafe { slice::from_raw_parts(slice.as_ptr().cast::<u16>(), slice.len() / 2) };
227+
Self::from_u16_with_nul(slice)
228+
}
229+
230+
/// Creates a `&CStr16` from a u16 slice, if the slice contains exactly
231+
/// one terminating null-byte and all chars are valid UCS-2 chars.
218232
pub fn from_u16_with_nul(codes: &[u16]) -> Result<&Self, FromSliceWithNulError> {
219233
for (pos, &code) in codes.iter().enumerate() {
220234
match code.try_into() {
@@ -234,7 +248,7 @@ impl CStr16 {
234248
Err(FromSliceWithNulError::NotNulTerminated)
235249
}
236250

237-
/// Unsafely creates a C string wrapper from a u16 slice.
251+
/// Unsafely creates a `&CStr16` from a u16 slice.
238252
///
239253
/// # Safety
240254
///
@@ -287,11 +301,13 @@ impl CStr16 {
287301
Self::from_u16_with_nul(&buf[..index + 1]).map_err(|err| match err {
288302
FromSliceWithNulError::InvalidChar(p) => FromStrWithBufError::InvalidChar(p),
289303
FromSliceWithNulError::InteriorNul(p) => FromStrWithBufError::InteriorNul(p),
290-
FromSliceWithNulError::NotNulTerminated => unreachable!(),
304+
FromSliceWithNulError::NotNulTerminated | FromSliceWithNulError::BrokenBuffer => {
305+
unreachable!()
306+
}
291307
})
292308
}
293309

294-
/// Create a [`CStr16`] from an [`UnalignedSlice`] using an aligned
310+
/// Create a `&CStr16` from an [`UnalignedSlice`] using an aligned
295311
/// buffer for storage. The lifetime of the output is tied to `buf`,
296312
/// not `src`.
297313
pub fn from_unaligned_slice<'buf>(
@@ -313,6 +329,7 @@ impl CStr16 {
313329
FromSliceWithNulError::InvalidChar(v) => UnalignedCStr16Error::InvalidChar(v),
314330
FromSliceWithNulError::InteriorNul(v) => UnalignedCStr16Error::InteriorNul(v),
315331
FromSliceWithNulError::NotNulTerminated => UnalignedCStr16Error::NotNulTerminated,
332+
FromSliceWithNulError::BrokenBuffer => UnalignedCStr16Error::BufferTooSmall,
316333
})
317334
}
318335

@@ -562,6 +579,13 @@ mod tests {
562579
assert_eq!(<CStr8 as Borrow<[u8]>>::borrow(string), &[b'a', 0]);
563580
}
564581

582+
#[test]
583+
fn test_cstr16_from_slice() {
584+
let s1 = CStr16::from_u8_with_nul(&[65, 0, 66, 0, 67, 0, 0, 0]).unwrap();
585+
let s2 = CStr16::from_u16_with_nul(&[65, 66, 67, 0]).unwrap();
586+
assert_eq!(s1, s2)
587+
}
588+
565589
#[test]
566590
fn test_cstr16_num_bytes() {
567591
let s = CStr16::from_u16_with_nul(&[65, 66, 67, 0]).unwrap();

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /