Skip to content

Commit 9de204a

Browse files
committed
fix aliasing UB, layout UB, and incorrect initialization UB
1 parent 0831245 commit 9de204a

5 files changed

Lines changed: 36 additions & 26 deletions

File tree

src/data/graph.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,10 @@ fn index_twice<T>(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
146146
} else if a == b {
147147
Pair::One(&mut arr[max(a, b)])
148148
} else {
149-
// safe because a, b are in bounds and distinct
150-
unsafe {
151-
let ar = &mut *(arr.get_unchecked_mut(a) as *mut _);
152-
let br = &mut *(arr.get_unchecked_mut(b) as *mut _);
153-
Pair::Both(ar, br)
154-
}
149+
// can't panic because a, b are in bounds and distinct
150+
let [ar,br] = arr.get_disjoint_mut([a,b]).unwrap();
151+
Pair::Both(ar, br)
152+
155153
}
156154
}
157155

src/dynamics/joint/multibody_joint/multibody.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ impl Force {
3030
}
3131

3232
fn as_vector(&self) -> &SVector<Real, SPATIAL_DIM> {
33+
// SAFETY : this is safe because :
34+
// - Force is repr(C)
35+
// - Vector is repr(C)
36+
// - AngVector is repr(C) or Real
37+
// - total size in Reals is SPATIAL_DIM
3338
unsafe { core::mem::transmute(self) }
3439
}
3540
}

src/dynamics/rigid_body_components.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ impl RigidBodyMassProps {
504504

505505
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
506506
#[derive(Clone, Debug, Copy, PartialEq)]
507+
#[repr(C)]
507508
/// The velocities of this rigid-body.
508509
pub struct RigidBodyVelocity<T: ScalarType> {
509510
/// The linear velocity of the rigid-body.
@@ -593,6 +594,11 @@ impl RigidBodyVelocity<Real> {
593594
#[inline]
594595
#[cfg(feature = "dim2")]
595596
pub fn as_vector(&self) -> &na::Vector3<Real> {
597+
// SAFETY : this is safe because :
598+
// - RigidBodyVelocity is repr(C)
599+
// - the vector types used are repr(C)
600+
// - the only non vector type is Real
601+
// - total size in Reals is 3
596602
unsafe { core::mem::transmute(self) }
597603
}
598604

@@ -602,6 +608,11 @@ impl RigidBodyVelocity<Real> {
602608
#[inline]
603609
#[cfg(feature = "dim2")]
604610
pub fn as_vector_mut(&mut self) -> &mut na::Vector3<Real> {
611+
// SAFETY : this is safe because :
612+
// - RigidBodyVelocity is repr(C)
613+
// - the vector types used are repr(C)
614+
// - the only non vector type is Real
615+
// - total size in Reals is 3
605616
unsafe { core::mem::transmute(self) }
606617
}
607618

@@ -611,6 +622,11 @@ impl RigidBodyVelocity<Real> {
611622
#[inline]
612623
#[cfg(feature = "dim3")]
613624
pub fn as_vector(&self) -> &na::Vector6<Real> {
625+
// SAFETY : this is safe because :
626+
// - RigidBodyVelocity is repr(C)
627+
// - the vector types used are repr(C)
628+
// - the only non vector type is Real
629+
// - total size in Reals is 6
614630
unsafe { core::mem::transmute(self) }
615631
}
616632

@@ -620,6 +636,11 @@ impl RigidBodyVelocity<Real> {
620636
#[inline]
621637
#[cfg(feature = "dim3")]
622638
pub fn as_vector_mut(&mut self) -> &mut na::Vector6<Real> {
639+
// SAFETY : this is safe because :
640+
// - RigidBodyVelocity is repr(C)
641+
// - the vector types used are repr(C)
642+
// - the only non vector type is Real
643+
// - total size in Reals is 6
623644
unsafe { core::mem::transmute(self) }
624645
}
625646

src/dynamics/solver/mod.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,7 @@ mod velocity_solver;
3434

3535
// TODO: SAFETY: restrict with bytemuck::Zeroable to make this safe.
3636
pub unsafe fn reset_buffer<T>(buffer: &mut Vec<T>, len: usize) {
37-
buffer.clear();
38-
buffer.reserve(len);
37+
buffer.clear();
3938

40-
unsafe {
41-
// NOTE: writing zeros is faster than u8::MAX.
42-
buffer.as_mut_ptr().write_bytes(0, len);
43-
buffer.set_len(len);
44-
}
39+
buffer.resize_with(len, || unsafe { core::mem::zeroed()})
4540
}

src/utils/index_mut2.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,7 @@ pub trait IndexMut2<I>: IndexMut<I> {
2525
impl<T> IndexMut2<usize> for Vec<T> {
2626
#[inline]
2727
fn index_mut2(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
28-
assert!(i != j, "Unable to index the same element twice.");
29-
assert!(i < self.len() && j < self.len(), "Index out of bounds.");
30-
31-
unsafe {
32-
let a = &mut *(self.get_unchecked_mut(i) as *mut _);
33-
let b = &mut *(self.get_unchecked_mut(j) as *mut _);
34-
(a, b)
35-
}
28+
<[T]>::index_mut2(self, i,j)
3629
}
3730
}
3831

@@ -42,10 +35,8 @@ impl<T> IndexMut2<usize> for [T] {
4235
assert!(i != j, "Unable to index the same element twice.");
4336
assert!(i < self.len() && j < self.len(), "Index out of bounds.");
4437

45-
unsafe {
46-
let a = &mut *(self.get_unchecked_mut(i) as *mut _);
47-
let b = &mut *(self.get_unchecked_mut(j) as *mut _);
48-
(a, b)
49-
}
38+
// cannot panic, per the above checks
39+
let [a,b] = self.get_disjoint_mut([i,j]).unwrap();
40+
(a,b)
5041
}
5142
}

0 commit comments

Comments
 (0)