-
-
Save thomcc/b2730e3b1a56c4d8cdebf29814ea2351 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
impl RawArray { | |
/// Returns if the pointer is within our bounds. | |
/// | |
/// If you intend to read a number of bytes, optionally you may providing a | |
/// size for the read. That said, if you provide a non-zero size, then `p` | |
/// needs to be strictly in-bounds -- it may not be the one-past-the-end | |
/// pointer when `size` is non-zero. | |
/// | |
/// Similar to computing `start_ptr <= P && P <= end_ptr` where `P` is both | |
/// `p` and `p.wrapping_add(size)`, but handles all the weird edge cases | |
/// correctly (in particular address aritmetic leading to wraparound). | |
/// | |
/// This is usally overkill, so it should probably only be used in asserts, | |
/// error checking, etc (ideally just asserts). Returning true does *not* | |
/// mean the read is legal (provenance may be invalid). | |
#[inline] | |
pub(crate) fn is_in_bounds(&self, p: *const u8, size: usize) -> bool { | |
if size >= isize::MAX as usize { | |
return false; | |
} | |
let base = self.ptr.as_ptr().cast::<u8>(); | |
let mem_size = unsafe { crate::varlena::varsize_any(base.cast()) }; | |
if size > mem_size { | |
return false; | |
} | |
let Ok(start_offset) = usize::try_from(ptr_diff_bytes(p, base)) else { | |
return false; | |
}; | |
if start_offset > mem_size { | |
return false; | |
} | |
if size == 0 { | |
return true; | |
} | |
let Ok(end_offset) = usize::try_from(ptr_diff_bytes(p.wrapping_add(size), base)) else { | |
return false; | |
} | |
end_offset <= mem_size && start_offset <= end_offset | |
} | |
} | |
#[inline] | |
fn wrapping_byte_offset_from(ptr: *const u8, base: *const u8) -> isize { | |
(ptr as usize).wrapping_sub(base as usize) as isize | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment