-
Notifications
You must be signed in to change notification settings - Fork 225
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Forbid use of as_slice when unaligned feature is enabled
- Loading branch information
Showing
3 changed files
with
62 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,9 +112,14 @@ impl<'a, T: PrimitiveElement> Reader<'a, T> { | |
} | ||
} | ||
|
||
#[cfg(target_endian = "little")] | ||
const _CHECK_SLICE: () = check_slice_supported::<T>(); | ||
|
||
/// Returns something if the slice is as expected in memory. | ||
/// | ||
/// If the target is not little-endian or the `unaligned` feature is enabled, this function | ||
/// will only be available for types that are 1 byte or smaller. | ||
pub fn as_slice(&self) -> Option<&[T]> { | ||
let () = Self::_CHECK_SLICE; | ||
Check warning on line 122 in capnp/src/primitive_list.rs GitHub Actions / lintthis let-binding has unit value
|
||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
as-com
Author
Contributor
|
||
if self.reader.get_element_size() == T::element_size() { | ||
let bytes = self.reader.into_raw_bytes(); | ||
let bits_per_element = data_bits_per_element(T::element_size()) as usize; | ||
|
@@ -137,6 +142,17 @@ impl<'a, T: PrimitiveElement> Reader<'a, T> { | |
} | ||
} | ||
|
||
const fn check_slice_supported<T: PrimitiveElement>() { | ||
if core::mem::size_of::<T>() > 1 { | ||
if !cfg!(target_endian = "little") { | ||
panic!("cannot call as_slice on primitive list of multi-byte elements on non-little endian targets"); | ||
} | ||
if cfg!(feature = "unaligned") { | ||
panic!("cannot call as_slice on primitive list of multi-byte elements when unaligned feature is enabled"); | ||
} | ||
} | ||
} | ||
|
||
impl<'a, T> crate::traits::IntoInternalListReader<'a> for Reader<'a, T> | ||
where | ||
T: PrimitiveElement, | ||
|
@@ -178,8 +194,10 @@ where | |
PrimitiveElement::set(&self.builder, index, value); | ||
} | ||
|
||
#[cfg(target_endian = "little")] | ||
const _CHECK_SLICE: () = check_slice_supported::<T>(); | ||
|
||
pub fn as_slice(&mut self) -> Option<&mut [T]> { | ||
let () = Self::_CHECK_SLICE; | ||
Check warning on line 200 in capnp/src/primitive_list.rs GitHub Actions / lintthis let-binding has unit value
|
||
if self.builder.get_element_size() == T::element_size() { | ||
let bytes = self.builder.as_raw_bytes(); | ||
let bits_per_element = data_bits_per_element(T::element_size()) as usize; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#![cfg(feature = "alloc")] | ||
|
||
use capnp::{message, primitive_list}; | ||
|
||
#[test] | ||
pub fn primitive_list_as_slice_small_values() { | ||
let mut msg = message::Builder::new_default(); | ||
|
||
{ | ||
let mut void_list = msg.initn_root::<primitive_list::Builder<()>>(0); | ||
assert_eq!(void_list.as_slice().unwrap().len(), 0); | ||
assert_eq!(void_list.into_reader().as_slice().unwrap().len(), 0); | ||
} | ||
|
||
{ | ||
let mut void_list = msg.initn_root::<primitive_list::Builder<()>>(5); | ||
assert_eq!(void_list.as_slice().unwrap(), &[(), (), (), (), ()]); | ||
assert_eq!( | ||
void_list.into_reader().as_slice().unwrap(), | ||
&[(), (), (), (), ()] | ||
); | ||
} | ||
|
||
{ | ||
let mut u8list = msg.initn_root::<primitive_list::Builder<u8>>(0); | ||
assert_eq!(u8list.as_slice().unwrap().len(), 0); | ||
assert_eq!(u8list.into_reader().as_slice().unwrap().len(), 0); | ||
} | ||
|
||
{ | ||
let mut u8list = msg.initn_root::<primitive_list::Builder<u8>>(3); | ||
u8list.set(0, 0); | ||
u8list.set(1, 1); | ||
u8list.set(2, 2); | ||
assert_eq!(u8list.as_slice().unwrap(), &[0, 1, 2]); | ||
} | ||
} |
@as-com do you know how to get rid of these clippy warnings? They are showing up in later PRs too:
/~https://github.com/capnproto/capnproto-rust/pull/502/files