/rust/registry/src/index.crates.io-6f17d22bba15001f/rkyv-0.7.44/src/validation/validators/shared.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Validators add validation capabilities by wrapping and extending basic validators. |
2 | | |
3 | | use crate::{validation::SharedContext, Fallible}; |
4 | | use core::{any::TypeId, fmt}; |
5 | | |
6 | | #[cfg(not(feature = "std"))] |
7 | | use hashbrown::HashMap; |
8 | | #[cfg(feature = "std")] |
9 | | use std::collections::HashMap; |
10 | | |
11 | | /// Errors that can occur when checking shared memory. |
12 | | #[derive(Debug)] |
13 | | pub enum SharedError { |
14 | | /// Multiple pointers exist to the same location with different types |
15 | | TypeMismatch { |
16 | | /// A previous type that the location was checked as |
17 | | previous: TypeId, |
18 | | /// The current type that the location is checked as |
19 | | current: TypeId, |
20 | | }, |
21 | | } |
22 | | |
23 | | impl fmt::Display for SharedError { |
24 | | #[inline] |
25 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
26 | 0 | match self { |
27 | 0 | SharedError::TypeMismatch { previous, current } => write!( |
28 | 0 | f, |
29 | 0 | "the same memory region has been claimed as two different types ({:?} and {:?})", |
30 | 0 | previous, current |
31 | 0 | ), |
32 | 0 | } |
33 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::fmt::Display>::fmt Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::fmt::Display>::fmt Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::fmt::Display>::fmt Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::fmt::Display>::fmt |
34 | | } |
35 | | |
36 | | #[cfg(feature = "std")] |
37 | | const _: () = { |
38 | | use std::error::Error; |
39 | | |
40 | | impl Error for SharedError { |
41 | 0 | fn source(&self) -> Option<&(dyn Error + 'static)> { |
42 | 0 | match self { |
43 | 0 | SharedError::TypeMismatch { .. } => None, |
44 | 0 | } |
45 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::error::Error>::source Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::error::Error>::source Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::error::Error>::source Unexecuted instantiation: <rkyv::validation::validators::shared::SharedError as core::error::Error>::source |
46 | | } |
47 | | }; |
48 | | |
49 | | /// A validator that can verify shared memory. |
50 | | #[derive(Debug)] |
51 | | pub struct SharedValidator { |
52 | | shared: HashMap<*const u8, TypeId>, |
53 | | } |
54 | | |
55 | | // SAFETY: SharedValidator is safe to send to another thread |
56 | | // This trait is not automatically implemented because the struct contains a pointer |
57 | | unsafe impl Send for SharedValidator {} |
58 | | |
59 | | // SAFETY: SharedValidator is safe to share between threads |
60 | | // This trait is not automatically implemented because the struct contains a pointer |
61 | | unsafe impl Sync for SharedValidator {} |
62 | | |
63 | | impl SharedValidator { |
64 | | /// Wraps the given context and adds shared memory validation. |
65 | | #[inline] |
66 | 0 | pub fn new() -> Self { |
67 | 0 | Self { |
68 | 0 | // TODO: consider deferring this to avoid the overhead of constructing |
69 | 0 | shared: HashMap::new(), |
70 | 0 | } |
71 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::new Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::new Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::new Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::new |
72 | | |
73 | | /// Shared memory validator with specific capacity. |
74 | | #[inline] |
75 | 0 | pub fn with_capacity(capacity: usize) -> Self { |
76 | 0 | Self { |
77 | 0 | shared: HashMap::with_capacity(capacity), |
78 | 0 | } |
79 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::with_capacity Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator>::with_capacity |
80 | | } |
81 | | |
82 | | impl Default for SharedValidator { |
83 | | #[inline] |
84 | 0 | fn default() -> Self { |
85 | 0 | Self::new() |
86 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as core::default::Default>::default Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as core::default::Default>::default |
87 | | } |
88 | | |
89 | | impl Fallible for SharedValidator { |
90 | | type Error = SharedError; |
91 | | } |
92 | | |
93 | | impl SharedContext for SharedValidator { |
94 | | #[inline] |
95 | 0 | fn register_shared_ptr( |
96 | 0 | &mut self, |
97 | 0 | ptr: *const u8, |
98 | 0 | type_id: TypeId, |
99 | 0 | ) -> Result<bool, Self::Error> { |
100 | 0 | #[cfg(not(feature = "std"))] |
101 | 0 | use hashbrown::hash_map::Entry; |
102 | 0 | #[cfg(feature = "std")] |
103 | 0 | use std::collections::hash_map::Entry; |
104 | 0 |
|
105 | 0 | match self.shared.entry(ptr) { |
106 | 0 | Entry::Occupied(previous_type_entry) => { |
107 | 0 | let previous_type_id = previous_type_entry.get(); |
108 | 0 | if previous_type_id != &type_id { |
109 | 0 | Err(SharedError::TypeMismatch { |
110 | 0 | previous: *previous_type_id, |
111 | 0 | current: type_id, |
112 | 0 | }) |
113 | | } else { |
114 | 0 | Ok(false) |
115 | | } |
116 | | } |
117 | 0 | Entry::Vacant(ent) => { |
118 | 0 | ent.insert(type_id); |
119 | 0 | Ok(true) |
120 | | } |
121 | | } |
122 | 0 | } Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as rkyv::validation::SharedContext>::register_shared_ptr Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as rkyv::validation::SharedContext>::register_shared_ptr Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as rkyv::validation::SharedContext>::register_shared_ptr Unexecuted instantiation: <rkyv::validation::validators::shared::SharedValidator as rkyv::validation::SharedContext>::register_shared_ptr |
123 | | } |