Struct rkyv::validation::ArchiveContext [−][src]
Context to perform archive validation.
When implementing archiveable containers, an archived type may point to some
bytes elsewhere in the archive using a RelPtr
. Before checking those
bytes, they must be claimed in the context. This prevents infinite-loop
attacks by malicious actors by ensuring that each block of memory has one
and only one owner.
Example
use core::{fmt, marker::PhantomData}; use std::error::Error; use rkyv::{ validation::{ArchiveContext, ArchiveMemoryError}, Archive, RelPtr, Resolve, Write, }; use bytecheck::{CheckBytes, Unreachable}; pub struct MyBox<T> { value: *mut T, } impl<T> MyBox<T> { fn new(value: T) -> Self { Self { value: Box::into_raw(Box::new(value)), } } fn value(&self) -> &T { unsafe { &*self.value } } } impl<T> Drop for MyBox<T> { fn drop(&mut self) { unsafe { Box::from_raw(self.value); } } } // A transparent representation guarantees us the same representation as // a RelPtr #[repr(transparent)] pub struct ArchivedMyBox<T> { value: RelPtr, _phantom: PhantomData<T>, } impl<T> ArchivedMyBox<T> { fn value(&self) -> &T { unsafe { &*self.value.as_ptr() } } } pub struct ArchivedMyBoxResolver { value_pos: usize, } impl<T: Archive> Resolve<MyBox<T>> for ArchivedMyBoxResolver { type Archived = ArchivedMyBox<T::Archived>; fn resolve(self, pos: usize, value: &MyBox<T>) -> Self::Archived { unsafe { ArchivedMyBox { value: RelPtr::new(pos, self.value_pos), _phantom: PhantomData, } } } } impl<T: Archive> Archive for MyBox<T> { type Archived = ArchivedMyBox<T::Archived>; type Resolver = ArchivedMyBoxResolver; fn archive<W: Write + ?Sized>(&self, writer: &mut W) -> Result<Self::Resolver, W::Error> { Ok(ArchivedMyBoxResolver { value_pos: writer.archive(self.value())?, }) } } #[derive(Debug)] pub enum ArchivedMyBoxError<T> { MemoryError(ArchiveMemoryError), CheckValueError(T), } impl<T: fmt::Display> fmt::Display for ArchivedMyBoxError<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ArchivedMyBoxError::MemoryError(e) => write!(f, "memory error: {}", e), ArchivedMyBoxError::CheckValueError(e) => write!(f, "check value error: {}", e), } } } impl<T: Error> Error for ArchivedMyBoxError<T> {} impl<T> From<Unreachable> for ArchivedMyBoxError<T> { fn from(e: Unreachable) -> Self { unreachable!() } } impl<T> From<ArchiveMemoryError> for ArchivedMyBoxError<T> { fn from(e: ArchiveMemoryError) -> Self { ArchivedMyBoxError::MemoryError(e) } } impl<T: CheckBytes<ArchiveContext>> CheckBytes<ArchiveContext> for ArchivedMyBox<T> { type Error = ArchivedMyBoxError<T::Error>; unsafe fn check_bytes<'a>( bytes: *const u8, context: &mut ArchiveContext ) -> Result<&'a Self, Self::Error> { let rel_ptr = RelPtr::check_bytes(bytes, context)?; let value_bytes = context.claim::<T>(rel_ptr, 1)?; T::check_bytes(value_bytes, context) .map_err(|e| ArchivedMyBoxError::CheckValueError(e))?; Ok(&*bytes.cast()) } }
Implementations
impl ArchiveContext
[src]
pub fn new(bytes: &[u8]) -> Self
[src]
Creates a new archive context for the given byte slice
pub unsafe fn claim<T: CheckBytes<ArchiveContext>>(
&mut self,
rel_ptr: &RelPtr,
count: usize
) -> Result<*const u8, ArchiveMemoryError>
[src]
&mut self,
rel_ptr: &RelPtr,
count: usize
) -> Result<*const u8, ArchiveMemoryError>
Claims count
items pointed to by the given relative pointer.
Safety
rel_ptr
must be inside the archive this context was created for.
pub unsafe fn claim_bytes(
&mut self,
base: *const u8,
offset: isize,
count: usize,
align: usize
) -> Result<*const u8, ArchiveMemoryError>
[src]
&mut self,
base: *const u8,
offset: isize,
count: usize,
align: usize
) -> Result<*const u8, ArchiveMemoryError>
Claims count
bytes located offset
bytes away from base
.
Safety
base
must be inside the archive this context was created for.
Trait Implementations
impl<T: CheckBytes<ArchiveContext>> CheckBytes<ArchiveContext> for ArchivedRef<T>
[src]
type Error = ArchivedRefError<T::Error>
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
impl<T: CheckBytes<ArchiveContext>> CheckBytes<ArchiveContext> for ArchivedSlice<T>
[src]
type Error = ArchivedSliceError<T::Error>
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
impl CheckBytes<ArchiveContext> for ArchivedStringSlice
[src]
type Error = ArchivedStringSliceError
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
impl<K: CheckBytes<ArchiveContext> + Eq + Hash, V: CheckBytes<ArchiveContext>> CheckBytes<ArchiveContext> for ArchivedHashMap<K, V>
[src]
type Error = ArchivedHashMapError<K::Error, V::Error>
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
impl<K: CheckBytes<ArchiveContext> + Hash + Eq> CheckBytes<ArchiveContext> for ArchivedHashSet<K>
[src]
type Error = ArchivedHashMapError<K::Error, <() as CheckBytes<ArchiveContext>>::Error>
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
impl CheckBytes<ArchiveContext> for RelPtr
[src]
type Error = Unreachable
The error that may result from validating the type.
unsafe fn check_bytes<'a>(
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
[src]
bytes: *const u8,
context: &mut ArchiveContext
) -> Result<&'a Self, Self::Error>
Auto Trait Implementations
impl RefUnwindSafe for ArchiveContext
[src]
impl !Send for ArchiveContext
[src]
impl !Sync for ArchiveContext
[src]
impl Unpin for ArchiveContext
[src]
impl UnwindSafe for ArchiveContext
[src]
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,