script: remove `unsafe` marker from slice-to-script conversions
The length of the slices is not a safety invariant. Fairly large diff because I had to remove a bunch of `unsafe` blocks around calls to this function. Fixes #3531
This commit is contained in:
parent
60841f689f
commit
4431df18fe
|
@ -47,32 +47,25 @@ mod primitive {
|
||||||
impl PushBytes {
|
impl PushBytes {
|
||||||
/// Creates `&PushBytes` without checking the length.
|
/// Creates `&PushBytes` without checking the length.
|
||||||
///
|
///
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The caller is responsible for checking that the length is less than the 2^32.
|
/// The caller is responsible for checking that the length is less than the 2^32.
|
||||||
unsafe fn from_slice_unchecked(bytes: &[u8]) -> &Self {
|
fn from_slice_unchecked(bytes: &[u8]) -> &Self {
|
||||||
// SAFETY: The caller must guarantee that bytes.len() < 2^32.
|
// SAFETY: The conversion is sound because &[u8] and &PushBytes
|
||||||
// If that is the case the conversion is sound because &[u8] and &PushBytes
|
|
||||||
// have the same layout (because of #[repr(transparent)] on PushBytes).
|
// have the same layout (because of #[repr(transparent)] on PushBytes).
|
||||||
&*(bytes as *const [u8] as *const PushBytes)
|
unsafe { &*(bytes as *const [u8] as *const PushBytes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates `&mut PushBytes` without checking the length.
|
/// Creates `&mut PushBytes` without checking the length.
|
||||||
///
|
///
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The caller is responsible for checking that the length is less than the 2^32.
|
/// The caller is responsible for checking that the length is less than the 2^32.
|
||||||
unsafe fn from_mut_slice_unchecked(bytes: &mut [u8]) -> &mut Self {
|
fn from_mut_slice_unchecked(bytes: &mut [u8]) -> &mut Self {
|
||||||
// SAFETY: The caller must guarantee that bytes.len() < 2^32.
|
// SAFETY: The conversion is sound because &mut [u8] and &mut PushBytes
|
||||||
// If that is the case the conversion is sound because &mut [u8] and &mut PushBytes
|
|
||||||
// have the same layout (because of #[repr(transparent)] on PushBytes).
|
// have the same layout (because of #[repr(transparent)] on PushBytes).
|
||||||
&mut *(bytes as *mut [u8] as *mut PushBytes)
|
unsafe { &mut *(bytes as *mut [u8] as *mut PushBytes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an empty `&PushBytes`.
|
/// Creates an empty `&PushBytes`.
|
||||||
pub fn empty() -> &'static Self {
|
pub fn empty() -> &'static Self {
|
||||||
// SAFETY: 0 < 2^32.
|
Self::from_slice_unchecked(&[])
|
||||||
unsafe { Self::from_slice_unchecked(&[]) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the underlying bytes.
|
/// Returns the underlying bytes.
|
||||||
|
@ -91,10 +84,7 @@ mod primitive {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn index(&self, index: $type) -> &Self::Output {
|
fn index(&self, index: $type) -> &Self::Output {
|
||||||
// SAFETY: Slicing can not make slices longer.
|
Self::from_slice_unchecked(&self.0[index])
|
||||||
unsafe {
|
|
||||||
Self::from_slice_unchecked(&self.0[index])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +92,7 @@ mod primitive {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn index_mut(&mut self, index: $type) -> &mut Self::Output {
|
fn index_mut(&mut self, index: $type) -> &mut Self::Output {
|
||||||
// SAFETY: Slicing can not make slices longer.
|
Self::from_mut_slice_unchecked(&mut self.0[index])
|
||||||
unsafe {
|
|
||||||
Self::from_mut_slice_unchecked(&mut self.0[index])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
@ -141,8 +128,7 @@ mod primitive {
|
||||||
|
|
||||||
fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
|
fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
|
||||||
check_limit(bytes.len())?;
|
check_limit(bytes.len())?;
|
||||||
// SAFETY: We've just checked the length.
|
Ok(PushBytes::from_slice_unchecked(bytes))
|
||||||
Ok(unsafe { PushBytes::from_slice_unchecked(bytes) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +137,7 @@ mod primitive {
|
||||||
|
|
||||||
fn try_from(bytes: &'a mut [u8]) -> Result<Self, Self::Error> {
|
fn try_from(bytes: &'a mut [u8]) -> Result<Self, Self::Error> {
|
||||||
check_limit(bytes.len())?;
|
check_limit(bytes.len())?;
|
||||||
// SAFETY: We've just checked the length.
|
Ok(PushBytes::from_mut_slice_unchecked(bytes))
|
||||||
Ok(unsafe { PushBytes::from_mut_slice_unchecked(bytes) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,16 +148,15 @@ mod primitive {
|
||||||
fn from(bytes: &'a [u8; $len]) -> Self {
|
fn from(bytes: &'a [u8; $len]) -> Self {
|
||||||
// Check that the macro wasn't called with a wrong number.
|
// Check that the macro wasn't called with a wrong number.
|
||||||
const _: () = [(); 1][($len >= 0x100000000u64) as usize];
|
const _: () = [(); 1][($len >= 0x100000000u64) as usize];
|
||||||
// SAFETY: We know the size of array statically and we checked macro input.
|
PushBytes::from_slice_unchecked(bytes)
|
||||||
unsafe { PushBytes::from_slice_unchecked(bytes) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a mut [u8; $len]> for &'a mut PushBytes {
|
impl<'a> From<&'a mut [u8; $len]> for &'a mut PushBytes {
|
||||||
fn from(bytes: &'a mut [u8; $len]) -> Self {
|
fn from(bytes: &'a mut [u8; $len]) -> Self {
|
||||||
// Macro check already above, no need to duplicate.
|
// Macro check already above, no need to duplicate.
|
||||||
// SAFETY: We know the size of array statically and we checked macro input.
|
// We know the size of array statically and we checked macro input.
|
||||||
unsafe { PushBytes::from_mut_slice_unchecked(bytes) }
|
PushBytes::from_mut_slice_unchecked(bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,13 +257,13 @@ mod primitive {
|
||||||
/// Extracts `PushBytes` slice
|
/// Extracts `PushBytes` slice
|
||||||
pub fn as_push_bytes(&self) -> &PushBytes {
|
pub fn as_push_bytes(&self) -> &PushBytes {
|
||||||
// length guaranteed by our invariant
|
// length guaranteed by our invariant
|
||||||
unsafe { PushBytes::from_slice_unchecked(&self.0) }
|
PushBytes::from_slice_unchecked(&self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts mutable `PushBytes` slice
|
/// Extracts mutable `PushBytes` slice
|
||||||
pub fn as_mut_push_bytes(&mut self) -> &mut PushBytes {
|
pub fn as_mut_push_bytes(&mut self) -> &mut PushBytes {
|
||||||
// length guaranteed by our invariant
|
// length guaranteed by our invariant
|
||||||
unsafe { PushBytes::from_mut_slice_unchecked(&mut self.0) }
|
PushBytes::from_mut_slice_unchecked(&mut self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accesses inner `Vec` - provided for `super` to impl other methods.
|
/// Accesses inner `Vec` - provided for `super` to impl other methods.
|
||||||
|
|
Loading…
Reference in New Issue