rkyv/rel_ptr/validation.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! Validation implementations for relative pointers
use crate::{
rel_ptr::{Offset, RawRelPtr, RelPtr},
ArchivePointee, Fallible,
};
use bytecheck::CheckBytes;
use core::{
convert::Infallible,
marker::{PhantomData, PhantomPinned},
ptr,
};
impl<O: Offset> RawRelPtr<O> {
/// Checks the bytes of the given raw relative pointer.
///
/// This is done rather than implementing `CheckBytes` to force users to manually write their
/// `CheckBytes` implementation since they need to also provide the ownership model of their
/// memory.
///
/// # Safety
///
/// The given pointer must be aligned and point to enough bytes to represent a `RawRelPtr`.
#[inline]
pub unsafe fn manual_check_bytes<'a, C: Fallible + ?Sized>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, Infallible>
where
O: CheckBytes<C>,
{
O::check_bytes(ptr::addr_of!((*value).offset), context).unwrap();
PhantomPinned::check_bytes(ptr::addr_of!((*value)._phantom), context).unwrap();
Ok(&*value)
}
}
impl<T: ArchivePointee + ?Sized, O: Offset> RelPtr<T, O> {
/// Checks the bytes of the given relative pointer.
///
/// This is done rather than implementing `CheckBytes` to force users to manually write their
/// `CheckBytes` implementation since they need to also provide the ownership model of their
/// memory.
///
/// # Safety
///
/// The given pointer must be aligned and point to enough bytes to represent a `RelPtr<T>`.
#[inline]
pub unsafe fn manual_check_bytes<'a, C: Fallible + ?Sized>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, <T::ArchivedMetadata as CheckBytes<C>>::Error>
where
O: CheckBytes<C>,
T::ArchivedMetadata: CheckBytes<C>,
{
RawRelPtr::manual_check_bytes(ptr::addr_of!((*value).raw_ptr), context).unwrap();
T::ArchivedMetadata::check_bytes(ptr::addr_of!((*value).metadata), context)?;
PhantomData::<T>::check_bytes(ptr::addr_of!((*value)._phantom), context).unwrap();
Ok(&*value)
}
}