rkyv/rel_ptr/
validation.rs

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