-
Notifications
You must be signed in to change notification settings - Fork 64
fn unaligned_lvl_slice: Safely encapsulate "unaligned" slices of lvl: &[[u8; 4]], as previous accesses were UB
#731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -341,6 +341,23 @@ pub(crate) unsafe fn rav1d_copy_lpf<BD: BitDepth>( | |
| } | ||
| } | ||
|
|
||
| /// Slice `[u8; 4]`s from `lvl`, but "unaligned", | ||
| /// meaning the `[u8; 4]`s can straddle | ||
| /// adjacent `[u8; 4]`s in the `lvl` slice. | ||
| /// | ||
| /// Note that this does not result in actual unaligned reads, | ||
| /// since `[u8; 4]` has an alignment of 1. | ||
| /// This optimizes to a single slice with a bounds check. | ||
| #[inline(always)] | ||
| fn unaligned_lvl_slice(lvl: &[[u8; 4]], y: usize) -> &[[u8; 4]] { | ||
| // Safety: `[u8; 4]` is transmutable to `u8`s. | ||
| let (_, lvl, _) = unsafe { lvl.align_to::<u8>() }; | ||
| let lvl = &lvl[y..]; | ||
| // Safety: `[u8; 4]` is transmutable to `u8`s. | ||
| let (_, lvl, _) = unsafe { lvl.align_to::<[u8; 4]>() }; | ||
| lvl | ||
| } | ||
|
|
||
kkysen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #[inline] | ||
| unsafe fn filter_plane_cols_y<BD: BitDepth>( | ||
| f: *const Rav1dFrameContext, | ||
|
|
@@ -377,7 +394,7 @@ unsafe fn filter_plane_cols_y<BD: BitDepth>( | |
| dst.offset((x * 4) as isize).cast(), | ||
| ls, | ||
| hmask.as_mut_ptr(), | ||
| lvl[x as usize][0..].as_ptr() as *const [u8; 4], | ||
| &lvl[x as usize], | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If enforcing a minimum slice size, this would be something like
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was hoping to structure things as, at this point in the code, we don't care about checking the length, as it is up to the inner
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that makes sense. If, down the road, we want the C/Rust fallbacks to check bounds, then we'll probably have to change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't change the existing As for asm |
||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| endy4 - starty4, | ||
|
|
@@ -416,7 +433,7 @@ unsafe fn filter_plane_rows_y<BD: BitDepth>( | |
| dst.cast(), | ||
| ls, | ||
| vmask.as_ptr(), | ||
| lvl[0][1..].as_ptr() as *const [u8; 4], | ||
| unaligned_lvl_slice(&lvl[0..], 1).as_ptr(), | ||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| w, | ||
|
|
@@ -462,7 +479,7 @@ unsafe fn filter_plane_cols_uv<BD: BitDepth>( | |
| u.offset((x * 4) as isize).cast(), | ||
| ls, | ||
| hmask.as_mut_ptr(), | ||
| lvl[x as usize][2..].as_ptr() as *const [u8; 4], | ||
| unaligned_lvl_slice(&lvl[x as usize..], 2).as_ptr(), | ||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| endy4 - starty4, | ||
|
|
@@ -472,7 +489,7 @@ unsafe fn filter_plane_cols_uv<BD: BitDepth>( | |
| v.offset((x * 4) as isize).cast(), | ||
| ls, | ||
| hmask.as_mut_ptr(), | ||
| lvl[x as usize][3..].as_ptr() as *const [u8; 4], | ||
| unaligned_lvl_slice(&lvl[x as usize..], 3).as_ptr(), | ||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| endy4 - starty4, | ||
|
|
@@ -512,7 +529,7 @@ unsafe fn filter_plane_rows_uv<BD: BitDepth>( | |
| u.offset(off_l as isize).cast(), | ||
| ls, | ||
| vmask.as_ptr(), | ||
| lvl[0][2..].as_ptr() as *const [u8; 4], | ||
| unaligned_lvl_slice(&lvl[0..], 2).as_ptr(), | ||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| w, | ||
|
|
@@ -522,7 +539,7 @@ unsafe fn filter_plane_rows_uv<BD: BitDepth>( | |
| v.offset(off_l as isize).cast(), | ||
| ls, | ||
| vmask.as_ptr(), | ||
| lvl[0][3..].as_ptr() as *const [u8; 4], | ||
| unaligned_lvl_slice(&lvl[0..], 3).as_ptr(), | ||
| b4_stride, | ||
| &(*f).lf.lim_lut.0, | ||
| w, | ||
|
|
@@ -687,10 +704,10 @@ pub(crate) unsafe fn rav1d_loopfilter_sbrow_cols<BD: BitDepth>( | |
| } | ||
| } | ||
| let mut ptr: *mut BD::Pixel; | ||
| let level_ptr = &(*f).lf.level[((*f).b4_stride * sby as isize * sbsz as isize) as usize..]; | ||
| let mut level_ptr = &(*f).lf.level[((*f).b4_stride * sby as isize * sbsz as isize) as usize..]; | ||
| ptr = p[0]; | ||
| have_left = 0 as c_int; | ||
| for (x, level_ptr) in (0..(*f).sb128w).zip(level_ptr.chunks(32)) { | ||
| for x in 0..(*f).sb128w { | ||
folkertdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| filter_plane_cols_y::<BD>( | ||
| f, | ||
| have_left, | ||
|
|
@@ -705,15 +722,17 @@ pub(crate) unsafe fn rav1d_loopfilter_sbrow_cols<BD: BitDepth>( | |
| ); | ||
| have_left = 1 as c_int; | ||
| ptr = ptr.offset(128); | ||
| level_ptr = &level_ptr[32..]; | ||
| } | ||
| if frame_hdr.loopfilter.level_u == 0 && frame_hdr.loopfilter.level_v == 0 { | ||
| return; | ||
| } | ||
| let mut uv_off: ptrdiff_t; | ||
| let level_ptr = &(*f).lf.level[((*f).b4_stride * (sby * sbsz >> ss_ver) as isize) as usize..]; | ||
| let mut level_ptr = | ||
| &(*f).lf.level[((*f).b4_stride * (sby * sbsz >> ss_ver) as isize) as usize..]; | ||
| have_left = 0 as c_int; | ||
| uv_off = 0; | ||
| for (x, level_ptr) in (0..(*f).sb128w).zip(level_ptr.chunks(32 >> ss_hor)) { | ||
| for x in 0..(*f).sb128w { | ||
| filter_plane_cols_uv::<BD>( | ||
| f, | ||
| have_left, | ||
|
|
@@ -730,6 +749,7 @@ pub(crate) unsafe fn rav1d_loopfilter_sbrow_cols<BD: BitDepth>( | |
| ); | ||
| have_left = 1 as c_int; | ||
| uv_off += 128 >> ss_hor; | ||
| level_ptr = &level_ptr[32 >> ss_hor..]; | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.