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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use super::{ArchivedBox, ArchivedString, ArchivedVec};
use crate::{
validation::{ArchiveBoundsContext, ArchiveMemoryContext, LayoutMetadata},
ArchivePointee, Fallible, RelPtr,
};
use bytecheck::CheckBytes;
use core::fmt;
use ptr_meta::Pointee;
use std::error::Error;
#[derive(Debug)]
pub enum OwnedPointerError<T, R, C> {
PointerCheckBytesError(T),
ValueCheckBytesError(R),
ContextError(C),
}
impl<T: fmt::Display, R: fmt::Display, C: fmt::Display> fmt::Display
for OwnedPointerError<T, R, C>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
OwnedPointerError::PointerCheckBytesError(e) => e.fmt(f),
OwnedPointerError::ValueCheckBytesError(e) => e.fmt(f),
OwnedPointerError::ContextError(e) => e.fmt(f),
}
}
}
impl<T: Error + 'static, R: Error + 'static, C: Error + 'static> Error
for OwnedPointerError<T, R, C>
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
OwnedPointerError::PointerCheckBytesError(e) => Some(e as &dyn Error),
OwnedPointerError::ValueCheckBytesError(e) => Some(e as &dyn Error),
OwnedPointerError::ContextError(e) => Some(e as &dyn Error),
}
}
}
type CheckOwnedPointerError<T, C> = OwnedPointerError<
<<T as ArchivePointee>::ArchivedMetadata as CheckBytes<C>>::Error,
<T as CheckBytes<C>>::Error,
<C as Fallible>::Error,
>;
impl<C: ArchiveBoundsContext + ArchiveMemoryContext + ?Sized> CheckBytes<C> for ArchivedString
where
C::Error: Error,
{
type Error = CheckOwnedPointerError<str, C>;
unsafe fn check_bytes<'a>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, Self::Error> {
let rel_ptr = RelPtr::<str>::manual_check_bytes(value.cast(), context)
.map_err(OwnedPointerError::PointerCheckBytesError)?;
let ptr = context
.claim_owned_rel_ptr(rel_ptr)
.map_err(OwnedPointerError::ContextError)?;
<str as CheckBytes<C>>::check_bytes(ptr, context)
.map_err(OwnedPointerError::ValueCheckBytesError)?;
Ok(&*value)
}
}
impl<
T: ArchivePointee + CheckBytes<C> + Pointee + ?Sized,
C: ArchiveBoundsContext + ArchiveMemoryContext + ?Sized,
> CheckBytes<C> for ArchivedBox<T>
where
T::ArchivedMetadata: CheckBytes<C>,
C::Error: Error,
<T as Pointee>::Metadata: LayoutMetadata<T>,
{
type Error =
OwnedPointerError<<T::ArchivedMetadata as CheckBytes<C>>::Error, T::Error, C::Error>;
unsafe fn check_bytes<'a>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, Self::Error> {
let rel_ptr = RelPtr::<T>::manual_check_bytes(value.cast(), context)
.map_err(OwnedPointerError::PointerCheckBytesError)?;
let ptr = context
.claim_owned_rel_ptr(rel_ptr)
.map_err(OwnedPointerError::ContextError)?;
T::check_bytes(ptr, context).map_err(OwnedPointerError::ValueCheckBytesError)?;
Ok(&*value)
}
}
impl<T: CheckBytes<C>, C: ArchiveBoundsContext + ArchiveMemoryContext + ?Sized> CheckBytes<C>
for ArchivedVec<T>
where
[T]: ArchivePointee,
<[T] as ArchivePointee>::ArchivedMetadata: CheckBytes<C>,
C::Error: Error,
<[T] as Pointee>::Metadata: LayoutMetadata<[T]>,
{
type Error = CheckOwnedPointerError<[T], C>;
unsafe fn check_bytes<'a>(
value: *const Self,
context: &mut C,
) -> Result<&'a Self, Self::Error> {
let rel_ptr = RelPtr::<[T]>::manual_check_bytes(value.cast(), context)
.map_err(OwnedPointerError::PointerCheckBytesError)?;
let ptr = context
.claim_owned_rel_ptr(rel_ptr)
.map_err(OwnedPointerError::ContextError)?;
<[T]>::check_bytes(ptr, context).map_err(OwnedPointerError::ValueCheckBytesError)?;
Ok(&*value)
}
}