Skip to content

Commit 0a5edd2

Browse files
CodesInChaosbarrbrain
authored andcommitted
Add debug assertions related to safety conditions
1 parent 92c05bd commit 0a5edd2

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

src/context/cdf_context.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,11 @@ impl<const CDF_LEN_MAX_PLUS_1: usize>
611611
let dst = self.data.as_mut_ptr().add(len) as *mut u16;
612612
let base = fc as *mut _ as *mut u8;
613613
let src = base.add(cdf.offset) as *const u16;
614+
// When CDF_LEN + 1 < CDF_LEN_MAX_PLUS_1, this reads beyond the end of
615+
// the slice described by `cdf`.
616+
// Since it is part of `CDFContext`, the out-of-bounds data is valid.
617+
// We conform to the stacked-borrows memory model by holding a mutable
618+
// ref to the containing data structure.
614619
dst.copy_from_nonoverlapping(src, CDF_LEN_MAX_PLUS_1 - 1);
615620
*dst.add(CDF_LEN_MAX_PLUS_1 - 1) = cdf.offset as u16;
616621
self.data.set_len(new_len);
@@ -630,10 +635,15 @@ impl<const CDF_LEN_MAX_PLUS_1: usize>
630635
unsafe {
631636
let mut src = self.data.as_mut_ptr().add(len);
632637
while len > checkpoint {
638+
// As checkpoint is unsigned, len > 0 is implied.
633639
len -= 1;
634640
src = src.sub(1);
635641
let src = src as *mut u16;
636642
let offset = *src.add(CDF_LEN_MAX_PLUS_1 - 1) as usize;
643+
debug_assert!(
644+
offset + (CDF_LEN_MAX_PLUS_1 - 1) * mem::size_of::<u16>()
645+
<= mem::size_of::<CDFContext>()
646+
);
637647
let dst = base.add(offset) as *mut u16;
638648
dst.copy_from_nonoverlapping(src, CDF_LEN_MAX_PLUS_1 - 1);
639649
}

src/dist.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,13 @@ pub(crate) mod rust {
142142

143143
// SAFETY: The length of data must be 16.
144144
unsafe fn hadamard4x4(data: &mut [i32]) {
145+
debug_assert_eq!(data.len(), 16);
145146
hadamard2d::<{ 4 * 4 }, 4, 4>(&mut *(data.as_mut_ptr() as *mut [i32; 16]));
146147
}
147148

148149
// SAFETY: The length of data must be 64.
149150
unsafe fn hadamard8x8(data: &mut [i32]) {
151+
debug_assert_eq!(data.len(), 64);
150152
hadamard2d::<{ 8 * 8 }, 8, 8>(&mut *(data.as_mut_ptr() as *mut [i32; 64]));
151153
}
152154

@@ -166,6 +168,7 @@ pub(crate) mod rust {
166168
// Size of hadamard transform should be 4x4 or 8x8
167169
// 4x* and *x4 use 4x4 and all other use 8x8
168170
let size: usize = w.min(h).min(8);
171+
debug_assert!(size == 4 || size == 8);
169172
let tx2d = if size == 4 { hadamard4x4 } else { hadamard8x8 };
170173

171174
let mut sum: u64 = 0;

src/lrf.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ pub(crate) mod rust {
194194
let ssq = get_integral_square(iimg_sq, iimg_stride, x, y, d);
195195
let (reta, retb) =
196196
sgrproj_sum_finish::<BD>(ssq, sum, n as u32, one_over_n, s);
197+
debug_assert!(x < af.len());
197198
*af.get_unchecked_mut(x) = reta;
199+
debug_assert!(x < bf.len());
198200
*bf.get_unchecked_mut(x) = retb;
199201
}
200202
}
@@ -369,9 +371,13 @@ unsafe fn get_integral_square(
369371
iimg: &[u32], stride: usize, x: usize, y: usize, size: usize,
370372
) -> u32 {
371373
// Cancel out overflow in iimg by using wrapping arithmetic
374+
debug_assert!(y * stride + x < iimg.len());
372375
let top_left = *iimg.get_unchecked(y * stride + x);
376+
debug_assert!(y * stride + x + size < iimg.len());
373377
let top_right = *iimg.get_unchecked(y * stride + x + size);
378+
debug_assert!((y + size) * stride + x < iimg.len());
374379
let bottom_left = *iimg.get_unchecked((y + size) * stride + x);
380+
debug_assert!((y + size) * stride + x + size < iimg.len());
375381
let bottom_right = *iimg.get_unchecked((y + size) * stride + x + size);
376382
top_left
377383
.wrapping_add(bottom_right)

src/util/align.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<T> AlignedBoxedSlice<T> {
6161
}
6262

6363
const fn layout(len: usize) -> Layout {
64-
// SAFETY: We are ensuring that `align` is non-zero and is a multiple of 2.
64+
// SAFETY: We are ensuring that `align` is non-zero and is a power of 2.
6565
unsafe {
6666
Layout::from_size_align_unchecked(
6767
len * mem::size_of::<T>(),

0 commit comments

Comments
 (0)