Skip to content

Commit 8eeb175

Browse files
CodesInChaosCodesInChaos
CodesInChaos
authored and
CodesInChaos
committed
Add debug assertions related to safety conditions
1 parent 92ed4e8 commit 8eeb175

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
@@ -601,6 +601,10 @@ trait CDFContextLogOps: CDFContextLogSize {
601601
let capacity = log.data.capacity();
602602
debug_assert!(new_len <= capacity);
603603
let dst = log.data.as_mut_ptr().add(len);
604+
// This reads beyond the end of `cdf`.
605+
// Since it's part of a larger data structure, the out-of-bounds data is valid.
606+
// However this violates the stacked-borrows memory model and is technically undefined behavior.
607+
// See https://github.com/xiph/rav1e/issues/3166
604608
dst.copy_from_nonoverlapping(cdf.as_ptr(), Self::CDF_LEN_MAX);
605609
*dst.add(Self::CDF_LEN_MAX) = offset as u16;
606610
log.data.set_len(new_len);
@@ -615,14 +619,20 @@ trait CDFContextLogOps: CDFContextLogSize {
615619
) {
616620
let base = fc as *mut _ as *mut u8;
617621
let mut len = log.data.len();
622+
debug_assert!(len % (Self::CDF_LEN_MAX + 1) == 0);
618623
// SAFETY: We use unchecked pointers here for performance.
619624
// Since we know the length, we can ensure not to go OOB.
620625
unsafe {
621626
let mut src = log.data.as_mut_ptr().add(len);
622627
while len > checkpoint {
628+
debug_assert!(len >= Self::CDF_LEN_MAX + 1);
623629
len -= Self::CDF_LEN_MAX + 1;
624630
src = src.sub(Self::CDF_LEN_MAX + 1);
625631
let offset = *src.add(Self::CDF_LEN_MAX) as usize;
632+
debug_assert!(
633+
offset + Self::CDF_LEN_MAX * mem::size_of::<u16>()
634+
<= mem::size_of::<CDFContext>()
635+
);
626636
let dst = base.add(offset) as *mut u16;
627637
dst.copy_from_nonoverlapping(src, Self::CDF_LEN_MAX);
628638
}

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)