rkyv_test/validation/validators/
mod.rs

1//! Validators that can check archived types.
2
3mod archive;
4mod shared;
5mod util;
6
7use crate::{
8    validation::{
9        check_archived_root_with_context, check_archived_value_with_context, ArchiveContext,
10        CheckTypeError, SharedContext,
11    },
12    Archive, Fallible,
13};
14pub use archive::*;
15use bytecheck::CheckBytes;
16use core::{alloc::Layout, any::TypeId, fmt};
17pub use shared::*;
18pub use util::*;
19
20/// The default validator error.
21#[derive(Debug)]
22pub enum DefaultValidatorError {
23    /// An archive validator error occurred.
24    ArchiveError(ArchiveError),
25    /// A shared validator error occurred.
26    SharedError(SharedError),
27}
28
29impl fmt::Display for DefaultValidatorError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            Self::ArchiveError(e) => write!(f, "{}", e),
33            Self::SharedError(e) => write!(f, "{}", e),
34        }
35    }
36}
37
38#[cfg(feature = "std")]
39const _: () = {
40    use std::error::Error;
41
42    impl Error for DefaultValidatorError {
43        fn source(&self) -> Option<&(dyn Error + 'static)> {
44            match self {
45                Self::ArchiveError(e) => Some(e as &dyn Error),
46                Self::SharedError(e) => Some(e as &dyn Error),
47            }
48        }
49    }
50};
51
52/// The default validator.
53#[derive(Debug)]
54pub struct DefaultValidator<'a> {
55    archive: ArchiveValidator<'a>,
56    shared: SharedValidator,
57}
58
59impl<'a> DefaultValidator<'a> {
60    /// Creates a new validator from a byte range.
61    #[inline]
62    pub fn new(bytes: &'a [u8]) -> Self {
63        Self {
64            archive: ArchiveValidator::new(bytes),
65            shared: SharedValidator::new(),
66        }
67    }
68}
69
70impl<'a> Fallible for DefaultValidator<'a> {
71    type Error = DefaultValidatorError;
72}
73
74impl<'a> ArchiveContext for DefaultValidator<'a> {
75    type PrefixRange = <ArchiveValidator<'a> as ArchiveContext>::PrefixRange;
76    type SuffixRange = <ArchiveValidator<'a> as ArchiveContext>::SuffixRange;
77
78    #[inline]
79    unsafe fn bounds_check_ptr(
80        &mut self,
81        base: *const u8,
82        offset: isize,
83    ) -> Result<*const u8, Self::Error> {
84        self.archive
85            .bounds_check_ptr(base, offset)
86            .map_err(DefaultValidatorError::ArchiveError)
87    }
88
89    #[inline]
90    unsafe fn bounds_check_layout(
91        &mut self,
92        data_address: *const u8,
93        layout: &Layout,
94    ) -> Result<(), Self::Error> {
95        self.archive
96            .bounds_check_layout(data_address, layout)
97            .map_err(DefaultValidatorError::ArchiveError)
98    }
99
100    #[inline]
101    unsafe fn bounds_check_subtree_ptr_layout(
102        &mut self,
103        data_address: *const u8,
104        layout: &Layout,
105    ) -> Result<(), Self::Error> {
106        self.archive
107            .bounds_check_subtree_ptr_layout(data_address, layout)
108            .map_err(DefaultValidatorError::ArchiveError)
109    }
110
111    #[inline]
112    unsafe fn push_prefix_subtree_range(
113        &mut self,
114        root: *const u8,
115        end: *const u8,
116    ) -> Result<PrefixRange, Self::Error> {
117        self.archive
118            .push_prefix_subtree_range(root, end)
119            .map_err(DefaultValidatorError::ArchiveError)
120    }
121
122    #[inline]
123    fn pop_prefix_range(&mut self, range: PrefixRange) -> Result<(), Self::Error> {
124        self.archive
125            .pop_prefix_range(range)
126            .map_err(DefaultValidatorError::ArchiveError)
127    }
128
129    #[inline]
130    unsafe fn push_suffix_subtree_range(
131        &mut self,
132        start: *const u8,
133        root: *const u8,
134    ) -> Result<SuffixRange, Self::Error> {
135        self.archive
136            .push_suffix_subtree_range(start, root)
137            .map_err(DefaultValidatorError::ArchiveError)
138    }
139
140    #[inline]
141    fn pop_suffix_range(&mut self, range: SuffixRange) -> Result<(), Self::Error> {
142        self.archive
143            .pop_suffix_range(range)
144            .map_err(DefaultValidatorError::ArchiveError)
145    }
146
147    #[inline]
148    fn finish(&mut self) -> Result<(), Self::Error> {
149        self.archive
150            .finish()
151            .map_err(DefaultValidatorError::ArchiveError)
152    }
153}
154
155impl<'a> SharedContext for DefaultValidator<'a> {
156    #[inline]
157    fn register_shared_ptr(
158        &mut self,
159        ptr: *const u8,
160        type_id: TypeId,
161    ) -> Result<bool, Self::Error> {
162        self.shared
163            .register_shared_ptr(ptr, type_id)
164            .map_err(DefaultValidatorError::SharedError)
165    }
166}
167
168/// Checks the given archive at the given position for an archived version of the given type.
169///
170/// This is a safe alternative to [`archived_value`](crate::archived_value) for types that implement
171/// `CheckBytes`.
172///
173/// # Examples
174/// ```
175/// use rkyv::{
176///     check_archived_value,
177///     ser::{Serializer, serializers::AlignedSerializer},
178///     AlignedVec,
179///     Archive,
180///     Serialize,
181/// };
182/// use bytecheck::CheckBytes;
183///
184/// #[derive(Archive, Serialize)]
185/// #[archive_attr(derive(CheckBytes))]
186/// struct Example {
187///     name: String,
188///     value: i32,
189/// }
190///
191/// let value = Example {
192///     name: "pi".to_string(),
193///     value: 31415926,
194/// };
195///
196/// let mut serializer = AlignedSerializer::new(AlignedVec::new());
197/// let pos = serializer.serialize_value(&value)
198///     .expect("failed to archive test");
199/// let buf = serializer.into_inner();
200/// let archived = check_archived_value::<Example>(buf.as_ref(), pos).unwrap();
201/// ```
202#[inline]
203pub fn check_archived_value<'a, T: Archive>(
204    bytes: &'a [u8],
205    pos: usize,
206) -> Result<&T::Archived, CheckTypeError<T::Archived, DefaultValidator<'a>>>
207where
208    T::Archived: CheckBytes<DefaultValidator<'a>>,
209{
210    let mut validator = DefaultValidator::new(bytes);
211    check_archived_value_with_context::<T, DefaultValidator>(bytes, pos, &mut validator)
212}
213
214/// Checks the given archive at the given position for an archived version of the given type.
215///
216/// This is a safe alternative to [`archived_value`](crate::archived_value) for types that implement
217/// `CheckBytes`.
218///
219/// See [`check_archived_value`] for more details.
220#[inline]
221pub fn check_archived_root<'a, T: Archive>(
222    bytes: &'a [u8],
223) -> Result<&'a T::Archived, CheckTypeError<T::Archived, DefaultValidator<'a>>>
224where
225    T::Archived: CheckBytes<DefaultValidator<'a>>,
226{
227    let mut validator = DefaultValidator::new(bytes);
228    check_archived_root_with_context::<T, DefaultValidator>(bytes, &mut validator)
229}