Skip to content

Commit

Permalink
Merge pull request #1131 from jturner314/fix-convert-to-view-check
Browse files Browse the repository at this point in the history
Add missing safety checks to `From<&[[A; N]]> for ArrayView` and `From<&mut [[A; N]]> for ArrayViewMut`
  • Loading branch information
bluss authored Mar 10, 2024
2 parents 3ed2022 + a68435d commit eb12613
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/arraytraits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,9 @@ where

/// Implementation of ArrayView2::from(&S) where S is a slice to a 2D array
///
/// **Panics** if the product of non-zero axis lengths overflows `isize` (This can only occur if A
/// is zero-sized because slices cannot contain more than `isize::MAX` number of bytes).
/// **Panics** if the product of non-zero axis lengths overflows `isize`. (This
/// can only occur if A is zero-sized or if `N` is zero, because slices cannot
/// contain more than `isize::MAX` number of bytes.)
impl<'a, A, const N: usize> From<&'a [[A; N]]> for ArrayView<'a, A, Ix2> {
/// Create a two-dimensional read-only array view of the data in `slice`
fn from(xs: &'a [[A; N]]) -> Self {
Expand All @@ -339,6 +340,11 @@ impl<'a, A, const N: usize> From<&'a [[A; N]]> for ArrayView<'a, A, Ix2> {
if size_of::<A>() == 0 {
dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
} else if N == 0 {
assert!(
xs.len() <= isize::MAX as usize,
"Product of non-zero axis lengths must not overflow isize.",
);
}

// `cols * rows` is guaranteed to fit in `isize` because we checked that it fits in
Expand Down Expand Up @@ -384,8 +390,9 @@ where

/// Implementation of ArrayViewMut2::from(&S) where S is a slice to a 2D array
///
/// **Panics** if the product of non-zero axis lengths overflows `isize` (This can only occur if A
/// is zero-sized because slices cannot contain more than `isize::MAX` number of bytes).
/// **Panics** if the product of non-zero axis lengths overflows `isize`. (This
/// can only occur if `A` is zero-sized or if `N` is zero, because slices
/// cannot contain more than `isize::MAX` number of bytes.)
impl<'a, A, const N: usize> From<&'a mut [[A; N]]> for ArrayViewMut<'a, A, Ix2> {
/// Create a two-dimensional read-write array view of the data in `slice`
fn from(xs: &'a mut [[A; N]]) -> Self {
Expand All @@ -395,6 +402,11 @@ impl<'a, A, const N: usize> From<&'a mut [[A; N]]> for ArrayViewMut<'a, A, Ix2>
if size_of::<A>() == 0 {
dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
} else if N == 0 {
assert!(
xs.len() <= isize::MAX as usize,
"Product of non-zero axis lengths must not overflow isize.",
);
}

// `cols * rows` is guaranteed to fit in `isize` because we checked that it fits in
Expand Down
23 changes: 23 additions & 0 deletions tests/array-construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,29 @@ fn deny_wraparound_uninit() {
let _five_large = Array::<f32, _>::uninit((3, 7, 29, 36760123, 823996703));
}

#[should_panic]
#[test]
fn deny_slice_with_too_many_rows_to_arrayview2() {
let _view = ArrayView2::from(&[[0u8; 0]; usize::MAX][..]);
}

#[should_panic]
#[test]
fn deny_slice_with_too_many_zero_sized_elems_to_arrayview2() {
let _view = ArrayView2::from(&[[(); isize::MAX as usize]; isize::MAX as usize][..]);
}

#[should_panic]
#[test]
fn deny_slice_with_too_many_rows_to_arrayviewmut2() {
let _view = ArrayViewMut2::from(&mut [[0u8; 0]; usize::MAX][..]);
}

#[should_panic]
#[test]
fn deny_slice_with_too_many_zero_sized_elems_to_arrayviewmut2() {
let _view = ArrayViewMut2::from(&mut [[(); isize::MAX as usize]; isize::MAX as usize][..]);
}

#[test]
fn maybe_uninit_1() {
Expand Down

0 comments on commit eb12613

Please sign in to comment.