Coverage Report

Created: 2024-10-16 07:58

/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
}