Coverage Report

Created: 2026-02-14 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/MigTD/src/policy/src/v1/config.rs
Line
Count
Source
1
// Copyright (c) 2022 Intel Corporation
2
//
3
// SPDX-License-Identifier: BSD-2-Clause-Patent
4
5
use alloc::{collections::BTreeMap, fmt::Write, string::String, vec::Vec};
6
use core::{mem::size_of, ops, str::FromStr};
7
use serde::{
8
    de::{Error, Visitor},
9
    Deserialize, Deserializer,
10
};
11
use td_shim_interface::td_uefi_pi::pi::guid::Guid;
12
13
#[derive(Debug, Deserialize)]
14
pub struct MigPolicy {
15
    #[serde(rename = "id", with = "guid_serde")]
16
    pub _id: Guid,
17
    #[serde(rename = "policy")]
18
    pub blocks: Vec<Policy>,
19
}
20
21
impl MigPolicy {
22
0
    pub fn get_platform_info_policy(&self) -> Vec<&PlatformInfo> {
23
0
        self.blocks
24
0
            .iter()
25
0
            .filter_map(|p| match p {
26
0
                Policy::Platform(p) => Some(p),
27
0
                _ => None,
28
0
            })
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy::{closure#0}
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy::{closure#0}
29
0
            .collect()
30
0
    }
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_platform_info_policy
31
32
0
    pub fn get_qe_info_policy(&self) -> Option<&QeInfo> {
33
0
        self.blocks.iter().find_map(|p| match p {
34
0
            Policy::Qe(q) => Some(q),
35
0
            _ => None,
36
0
        })
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy::{closure#0}
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy::{closure#0}
37
0
    }
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_qe_info_policy
38
39
0
    pub fn get_migtd_info_policy(&self) -> Option<&MigTdInfo> {
40
0
        self.blocks.iter().find_map(|p| match p {
41
0
            Policy::Migtd(m) => Some(m),
42
0
            _ => None,
43
0
        })
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy::{closure#0}
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy::{closure#0}
44
0
    }
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy
Unexecuted instantiation: <policy::v1::config::MigPolicy>::get_migtd_info_policy
45
}
46
47
#[derive(Debug, Deserialize)]
48
#[serde(untagged)]
49
pub enum Policy {
50
    Platform(PlatformInfo),
51
    Qe(QeInfo),
52
    TdxModule(TdxModuleInfo),
53
    Migtd(MigTdInfo),
54
}
55
56
#[derive(Debug, Deserialize)]
57
pub struct PlatformInfo {
58
    pub(crate) fmspc: String,
59
    #[serde(rename = "Platform")]
60
    pub(crate) platform: Platform,
61
}
62
63
#[derive(Debug, Deserialize)]
64
pub(crate) struct Platform {
65
    #[serde(rename = "TcbInfo")]
66
    pub(crate) tcb_info: BTreeMap<String, Property>,
67
}
68
69
#[derive(Debug, Deserialize)]
70
pub struct QeInfo {
71
    #[serde(rename = "QE")]
72
    pub(crate) qe_identity: QeIdentity,
73
}
74
75
#[derive(Debug, Deserialize)]
76
pub(crate) struct QeIdentity {
77
    #[serde(rename = "QeIdentity")]
78
    pub(crate) qe_identity: BTreeMap<String, Property>,
79
}
80
81
#[derive(Debug, Deserialize)]
82
pub struct TdxModuleInfo {
83
    #[serde(rename = "TDXModule")]
84
    pub(crate) tdx_module: TdxModule,
85
}
86
87
#[derive(Debug, Deserialize)]
88
pub(crate) struct TdxModule {
89
    #[serde(rename = "TDXModule_Identity")]
90
    pub(crate) tdx_module_identity: BTreeMap<String, Property>,
91
}
92
93
#[derive(Debug, Deserialize)]
94
pub struct MigTdInfo {
95
    #[serde(rename = "MigTD")]
96
    pub(crate) migtd: TdInfo,
97
}
98
99
#[derive(Debug, Deserialize)]
100
pub(crate) struct TdInfo {
101
    #[serde(rename = "TDINFO")]
102
    pub(crate) td_info: BTreeMap<String, Property>,
103
    #[serde(rename = "EventLog")]
104
    pub(crate) event_log: Option<BTreeMap<String, Property>>,
105
}
106
107
#[derive(Debug, Deserialize, Clone)]
108
pub struct Property {
109
    pub(crate) operation: Operation,
110
    pub(crate) reference: Reference,
111
}
112
113
impl Property {
114
0
    pub fn verify(&self, is_src: bool, local: &[u8], peer: &[u8]) -> bool {
115
0
        match &self.reference {
116
0
            Reference::Integer(i) => {
117
0
                if peer.len() > size_of::<usize>() {
118
0
                    false
119
                } else {
120
0
                    let mut bytes = [0u8; size_of::<usize>()];
121
0
                    bytes[..peer.len()].copy_from_slice(peer);
122
0
                    let peer = usize::from_le_bytes(bytes);
123
0
                    i.verify(is_src, &self.operation, 0, peer)
124
                }
125
            }
126
0
            Reference::String(s) => {
127
0
                let peer = format_bytes_hex(peer);
128
0
                s.verify(is_src, &self.operation, "", &peer)
129
            }
130
0
            Reference::Local(selfr) => selfr.verify(is_src, &self.operation, local, peer),
131
0
            Reference::IntegerRange(r) => {
132
0
                if peer.len() > size_of::<usize>() {
133
0
                    false
134
                } else {
135
0
                    let mut bytes = [0u8; size_of::<usize>()];
136
0
                    bytes[..peer.len()].copy_from_slice(peer);
137
0
                    let peer = usize::from_le_bytes(bytes);
138
0
                    r.verify(is_src, &self.operation, 0, peer)
139
                }
140
            }
141
0
            Reference::Array(a) => a.verify(is_src, &self.operation, &[], peer),
142
        }
143
0
    }
Unexecuted instantiation: <policy::v1::config::Property>::verify
Unexecuted instantiation: <policy::v1::config::Property>::verify
144
}
145
146
#[derive(Debug, Clone)]
147
pub(crate) enum Reference {
148
    Integer(Integer),
149
    String(RefString),
150
    Local(RefLocal),
151
    IntegerRange(IntegerRange),
152
    Array(Array), // TimeRange(ops::Range<usize>),
153
}
154
155
impl<'de> Deserialize<'de> for Reference {
156
295k
    fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error>
157
295k
    where
158
295k
        D: Deserializer<'de>,
159
    {
160
        struct ReferenceVisitor;
161
162
281k
        fn parse_str(s: &str) -> Option<Reference> {
163
281k
            if s == "self" {
164
50.6k
                Some(Reference::Local(RefLocal))
165
230k
            } else if let Some(range) = parse_range(s) {
166
2.38k
                Some(Reference::IntegerRange(IntegerRange(range)))
167
            } else {
168
228k
                Some(Reference::String(RefString(String::from_str(s).ok()?)))
169
            }
170
281k
        }
Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::parse_str
<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::parse_str
Line
Count
Source
162
281k
        fn parse_str(s: &str) -> Option<Reference> {
163
281k
            if s == "self" {
164
50.6k
                Some(Reference::Local(RefLocal))
165
230k
            } else if let Some(range) = parse_range(s) {
166
2.38k
                Some(Reference::IntegerRange(IntegerRange(range)))
167
            } else {
168
228k
                Some(Reference::String(RefString(String::from_str(s).ok()?)))
169
            }
170
281k
        }
171
172
        impl<'de> Visitor<'de> for ReferenceVisitor {
173
            type Value = Reference;
174
175
281k
            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
176
281k
            where
177
281k
                E: Error,
178
            {
179
281k
                parse_str(v).ok_or(E::custom("Invalid string value"))
180
281k
            }
Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error>
<<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error>
Line
Count
Source
175
281k
            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
176
281k
            where
177
281k
                E: Error,
178
            {
179
281k
                parse_str(v).ok_or(E::custom("Invalid string value"))
180
281k
            }
181
182
5.98k
            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
183
5.98k
            where
184
5.98k
                E: Error,
185
            {
186
5.98k
                Ok(Reference::Integer(Integer(v as usize)))
187
5.98k
            }
Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_u64::<serde_json::error::Error>
<<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_u64::<serde_json::error::Error>
Line
Count
Source
182
5.98k
            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
183
5.98k
            where
184
5.98k
                E: Error,
185
            {
186
5.98k
                Ok(Reference::Integer(Integer(v as usize)))
187
5.98k
            }
188
189
6.87k
            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
190
6.87k
            where
191
6.87k
                A: serde::de::SeqAccess<'de>,
192
            {
193
6.87k
                let mut items = Vec::new();
194
1.78M
                while let Some(val) = seq.next_element()? {
195
1.77M
                    items.push(val);
196
1.77M
                }
197
5.55k
                Ok(Reference::Array(Array(items)))
198
6.87k
            }
Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_seq::<&mut serde::de::value::SeqDeserializer<core::iter::adapters::map::Map<core::slice::iter::Iter<serde::__private::de::content::Content>, <serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>::new>, serde_json::error::Error>>
<<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::visit_seq::<&mut serde::de::value::SeqDeserializer<core::iter::adapters::map::Map<core::slice::iter::Iter<serde::__private::de::content::Content>, <serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>::new>, serde_json::error::Error>>
Line
Count
Source
189
6.87k
            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
190
6.87k
            where
191
6.87k
                A: serde::de::SeqAccess<'de>,
192
            {
193
6.87k
                let mut items = Vec::new();
194
1.78M
                while let Some(val) = seq.next_element()? {
195
1.77M
                    items.push(val);
196
1.77M
                }
197
5.55k
                Ok(Reference::Array(Array(items)))
198
6.87k
            }
199
200
1.17k
            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
201
1.17k
                formatter.write_str("Expect a sequence of map or a string value")
202
1.17k
            }
Unexecuted instantiation: <<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::expecting
<<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::ReferenceVisitor as serde::de::Visitor>::expecting
Line
Count
Source
200
1.17k
            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
201
1.17k
                formatter.write_str("Expect a sequence of map or a string value")
202
1.17k
            }
203
        }
204
205
295k
        deserializer.deserialize_any(ReferenceVisitor)
206
295k
    }
Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>
Unexecuted instantiation: <policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>>
<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>
Line
Count
Source
156
295k
    fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error>
157
295k
    where
158
295k
        D: Deserializer<'de>,
159
    {
160
        struct ReferenceVisitor;
161
162
        fn parse_str(s: &str) -> Option<Reference> {
163
            if s == "self" {
164
                Some(Reference::Local(RefLocal))
165
            } else if let Some(range) = parse_range(s) {
166
                Some(Reference::IntegerRange(IntegerRange(range)))
167
            } else {
168
                Some(Reference::String(RefString(String::from_str(s).ok()?)))
169
            }
170
        }
171
172
        impl<'de> Visitor<'de> for ReferenceVisitor {
173
            type Value = Reference;
174
175
            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
176
            where
177
                E: Error,
178
            {
179
                parse_str(v).ok_or(E::custom("Invalid string value"))
180
            }
181
182
            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
183
            where
184
                E: Error,
185
            {
186
                Ok(Reference::Integer(Integer(v as usize)))
187
            }
188
189
            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
190
            where
191
                A: serde::de::SeqAccess<'de>,
192
            {
193
                let mut items = Vec::new();
194
                while let Some(val) = seq.next_element()? {
195
                    items.push(val);
196
                }
197
                Ok(Reference::Array(Array(items)))
198
            }
199
200
            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
201
                formatter.write_str("Expect a sequence of map or a string value")
202
            }
203
        }
204
205
295k
        deserializer.deserialize_any(ReferenceVisitor)
206
295k
    }
<policy::v1::config::Reference as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>>
Line
Count
Source
156
207
    fn deserialize<D>(deserializer: D) -> Result<Reference, D::Error>
157
207
    where
158
207
        D: Deserializer<'de>,
159
    {
160
        struct ReferenceVisitor;
161
162
        fn parse_str(s: &str) -> Option<Reference> {
163
            if s == "self" {
164
                Some(Reference::Local(RefLocal))
165
            } else if let Some(range) = parse_range(s) {
166
                Some(Reference::IntegerRange(IntegerRange(range)))
167
            } else {
168
                Some(Reference::String(RefString(String::from_str(s).ok()?)))
169
            }
170
        }
171
172
        impl<'de> Visitor<'de> for ReferenceVisitor {
173
            type Value = Reference;
174
175
            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
176
            where
177
                E: Error,
178
            {
179
                parse_str(v).ok_or(E::custom("Invalid string value"))
180
            }
181
182
            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
183
            where
184
                E: Error,
185
            {
186
                Ok(Reference::Integer(Integer(v as usize)))
187
            }
188
189
            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
190
            where
191
                A: serde::de::SeqAccess<'de>,
192
            {
193
                let mut items = Vec::new();
194
                while let Some(val) = seq.next_element()? {
195
                    items.push(val);
196
                }
197
                Ok(Reference::Array(Array(items)))
198
            }
199
200
            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
201
                formatter.write_str("Expect a sequence of map or a string value")
202
            }
203
        }
204
205
207
        deserializer.deserialize_any(ReferenceVisitor)
206
207
    }
207
}
208
209
#[derive(Debug, PartialEq, Clone)]
210
pub(crate) enum Operation {
211
    Equal,
212
    GreaterOrEqual,
213
    Subset,
214
    InRange,
215
    InTimeRange,
216
    ArrayEqual,
217
    ArrayGreaterOrEqual,
218
}
219
220
impl<'de> Deserialize<'de> for Operation {
221
300k
    fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error>
222
300k
    where
223
300k
        D: Deserializer<'de>,
224
    {
225
300k
        let s: &str = Deserialize::deserialize(deserializer)?;
226
295k
        match s {
227
295k
            "equal" => Ok(Operation::Equal),
228
32.1k
            "greater-or-equal" => Ok(Operation::GreaterOrEqual),
229
31.8k
            "subset" => Ok(Operation::Subset),
230
30.7k
            "in-range" => Ok(Operation::InRange),
231
29.8k
            "in-time-range" => Ok(Operation::InTimeRange),
232
29.4k
            "array-equal" => Ok(Operation::ArrayEqual),
233
3.00k
            "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual),
234
2.80k
            _ => Err(D::Error::custom("Unknown operation")),
235
        }
236
300k
    }
Unexecuted instantiation: <policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>
Unexecuted instantiation: <policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>>
<policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::content::ContentRefDeserializer<serde_json::error::Error>>
Line
Count
Source
221
297k
    fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error>
222
297k
    where
223
297k
        D: Deserializer<'de>,
224
    {
225
297k
        let s: &str = Deserialize::deserialize(deserializer)?;
226
295k
        match s {
227
295k
            "equal" => Ok(Operation::Equal),
228
32.1k
            "greater-or-equal" => Ok(Operation::GreaterOrEqual),
229
31.8k
            "subset" => Ok(Operation::Subset),
230
30.7k
            "in-range" => Ok(Operation::InRange),
231
29.8k
            "in-time-range" => Ok(Operation::InTimeRange),
232
29.4k
            "array-equal" => Ok(Operation::ArrayEqual),
233
3.00k
            "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual),
234
2.80k
            _ => Err(D::Error::custom("Unknown operation")),
235
        }
236
297k
    }
<policy::v1::config::Operation as serde::de::Deserialize>::deserialize::<serde::__private::de::missing_field::MissingFieldDeserializer<serde_json::error::Error>>
Line
Count
Source
221
2.86k
    fn deserialize<D>(deserializer: D) -> Result<Operation, D::Error>
222
2.86k
    where
223
2.86k
        D: Deserializer<'de>,
224
    {
225
2.86k
        let s: &str = Deserialize::deserialize(deserializer)?;
226
0
        match s {
227
0
            "equal" => Ok(Operation::Equal),
228
0
            "greater-or-equal" => Ok(Operation::GreaterOrEqual),
229
0
            "subset" => Ok(Operation::Subset),
230
0
            "in-range" => Ok(Operation::InRange),
231
0
            "in-time-range" => Ok(Operation::InTimeRange),
232
0
            "array-equal" => Ok(Operation::ArrayEqual),
233
0
            "array-greater-or-equal" => Ok(Operation::ArrayGreaterOrEqual),
234
0
            _ => Err(D::Error::custom("Unknown operation")),
235
        }
236
2.86k
    }
237
}
238
239
#[derive(Debug, Clone)]
240
pub(crate) struct Integer(usize);
241
242
impl Integer {
243
0
    fn verify(&self, _is_src: bool, op: &Operation, _local: usize, peer: usize) -> bool {
244
0
        match op {
245
0
            Operation::Equal => peer == self.0,
246
0
            Operation::GreaterOrEqual => peer >= self.0,
247
0
            _ => false,
248
        }
249
0
    }
Unexecuted instantiation: <policy::v1::config::Integer>::verify
Unexecuted instantiation: <policy::v1::config::Integer>::verify
250
}
251
252
#[derive(Debug, Clone)]
253
pub(crate) struct RefString(pub(crate) String);
254
255
impl RefString {
256
0
    pub(crate) fn verify(&self, _is_src: bool, op: &Operation, _local: &str, peer: &str) -> bool {
257
0
        match op {
258
0
            Operation::Equal => *peer == self.0,
259
0
            _ => false,
260
        }
261
0
    }
Unexecuted instantiation: <policy::v1::config::RefString>::verify
Unexecuted instantiation: <policy::v1::config::RefString>::verify
262
}
263
264
#[derive(Debug, Clone)]
265
pub(crate) struct RefLocal;
266
267
impl RefLocal {
268
0
    fn verify(&self, is_src: bool, op: &Operation, local: &[u8], peer: &[u8]) -> bool {
269
0
        if local.len() != peer.len() {
270
0
            return false;
271
0
        }
272
0
        match op {
273
0
            Operation::Equal => peer == local,
274
            Operation::GreaterOrEqual => {
275
0
                if let Some(l) = slice_to_u64(local) {
276
0
                    if let Some(p) = slice_to_u64(peer) {
277
0
                        return if is_src { p >= l } else { l >= p };
278
0
                    }
279
0
                }
280
0
                false
281
            }
282
0
            Operation::ArrayEqual => local == peer,
283
            Operation::ArrayGreaterOrEqual => {
284
0
                local
285
0
                    .iter()
286
0
                    .zip(peer.iter())
287
0
                    .all(|(l, p)| if is_src { p >= l } else { l >= p })
Unexecuted instantiation: <policy::v1::config::RefLocal>::verify::{closure#0}
Unexecuted instantiation: <policy::v1::config::RefLocal>::verify::{closure#0}
288
            }
289
0
            _ => false,
290
        }
291
0
    }
Unexecuted instantiation: <policy::v1::config::RefLocal>::verify
Unexecuted instantiation: <policy::v1::config::RefLocal>::verify
292
}
293
294
#[derive(Debug, Clone)]
295
pub(crate) struct IntegerRange(ops::Range<usize>);
296
297
impl IntegerRange {
298
0
    fn verify(&self, _is_src: bool, op: &Operation, _local: usize, peer: usize) -> bool {
299
0
        match op {
300
0
            Operation::InRange => self.0.contains(&peer),
301
0
            Operation::InTimeRange => self.0.contains(&peer),
302
0
            _ => false,
303
        }
304
0
    }
Unexecuted instantiation: <policy::v1::config::IntegerRange>::verify
Unexecuted instantiation: <policy::v1::config::IntegerRange>::verify
305
}
306
307
230k
fn parse_range(input: &str) -> Option<ops::Range<usize>> {
308
230k
    let parts: Vec<&str> = input.split("..").collect();
309
310
230k
    if parts.len() != 2 {
311
217k
        return None;
312
13.0k
    }
313
314
13.0k
    let start = if parts[0].is_empty() {
315
7.74k
        usize::MIN
316
    } else {
317
5.27k
        usize::from_str(parts[0]).ok()?
318
    };
319
320
10.7k
    let end: usize = if parts[1].is_empty() {
321
1.35k
        usize::MAX
322
    } else {
323
9.44k
        usize::from_str(parts[1]).ok()?
324
    };
325
326
2.38k
    Some(start..end)
327
230k
}
Unexecuted instantiation: policy::v1::config::parse_range
policy::v1::config::parse_range
Line
Count
Source
307
230k
fn parse_range(input: &str) -> Option<ops::Range<usize>> {
308
230k
    let parts: Vec<&str> = input.split("..").collect();
309
310
230k
    if parts.len() != 2 {
311
217k
        return None;
312
13.0k
    }
313
314
13.0k
    let start = if parts[0].is_empty() {
315
7.74k
        usize::MIN
316
    } else {
317
5.27k
        usize::from_str(parts[0]).ok()?
318
    };
319
320
10.7k
    let end: usize = if parts[1].is_empty() {
321
1.35k
        usize::MAX
322
    } else {
323
9.44k
        usize::from_str(parts[1]).ok()?
324
    };
325
326
2.38k
    Some(start..end)
327
230k
}
328
329
#[derive(Debug, Clone)]
330
pub(crate) struct Array(Vec<u8>);
331
332
impl Array {
333
0
    fn verify(&self, _is_src: bool, op: &Operation, _local: &[u8], peer: &[u8]) -> bool {
334
0
        if peer.len() != self.0.len() {
335
0
            return false;
336
0
        }
337
338
0
        match op {
339
0
            Operation::ArrayEqual => self.0.as_slice() == peer,
340
0
            Operation::ArrayGreaterOrEqual => self.0.iter().zip(peer.iter()).all(|(r, p)| p >= r),
Unexecuted instantiation: <policy::v1::config::Array>::verify::{closure#0}
Unexecuted instantiation: <policy::v1::config::Array>::verify::{closure#0}
341
0
            _ => false,
342
        }
343
0
    }
Unexecuted instantiation: <policy::v1::config::Array>::verify
Unexecuted instantiation: <policy::v1::config::Array>::verify
344
}
345
346
mod guid_serde {
347
    use super::*;
348
349
476
    pub fn deserialize<'de, D>(deserializer: D) -> Result<Guid, D::Error>
350
476
    where
351
476
        D: Deserializer<'de>,
352
    {
353
476
        let s: &str = Deserialize::deserialize(deserializer)?;
354
198
        Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID"))
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>::{closure#0}
policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>>::{closure#0}
Line
Count
Source
354
104
        Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID"))
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>::{closure#0}
355
476
    }
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>
policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>>
Line
Count
Source
349
476
    pub fn deserialize<'de, D>(deserializer: D) -> Result<Guid, D::Error>
350
476
    where
351
476
        D: Deserializer<'de>,
352
    {
353
476
        let s: &str = Deserialize::deserialize(deserializer)?;
354
198
        Guid::from_str(s).map_err(|_| Error::custom("Invalid GUID"))
355
476
    }
Unexecuted instantiation: policy::v1::config::guid_serde::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::StrRead>>
356
}
357
358
0
pub(crate) fn slice_to_u64(input: &[u8]) -> Option<u64> {
359
0
    if input.len() > size_of::<u64>() {
360
0
        return None;
361
0
    }
362
0
    let mut bytes = [0u8; 8];
363
0
    bytes[..input.len()].copy_from_slice(input);
364
0
    Some(u64::from_le_bytes(bytes))
365
0
}
Unexecuted instantiation: policy::v1::config::slice_to_u64
Unexecuted instantiation: policy::v1::config::slice_to_u64
366
367
0
pub(crate) fn format_bytes_hex(input: &[u8]) -> String {
368
0
    input.iter().fold(String::new(), |mut acc, b| {
369
0
        let _ = write!(acc, "{b:02X}");
370
0
        acc
371
0
    })
Unexecuted instantiation: policy::v1::config::format_bytes_hex::{closure#0}
Unexecuted instantiation: policy::v1::config::format_bytes_hex::{closure#0}
372
0
}
Unexecuted instantiation: policy::v1::config::format_bytes_hex
Unexecuted instantiation: policy::v1::config::format_bytes_hex
373
374
#[cfg(test)]
375
mod test {
376
    use super::*;
377
    use alloc::vec;
378
379
    #[test]
380
    fn test_policy_data() {
381
        use super::*;
382
        use serde_json;
383
384
        let result = serde_json::from_str::<MigPolicy>(include_str!("../../test/policy.json"));
385
        assert!(result.is_ok());
386
    }
387
388
    #[test]
389
    fn test_policy_data_with_invalid_guid() {
390
        use super::*;
391
        use serde_json;
392
393
        let result =
394
            serde_json::from_str::<MigPolicy>(include_str!("../../test/policy_invalid_guid.json"));
395
        assert!(result.is_err());
396
    }
397
398
    #[test]
399
    fn test_invalid_policy_data() {
400
        use super::*;
401
        use serde_json;
402
403
        let result = serde_json::from_str::<MigPolicy>(include_str!("../../test/policy_005.json"));
404
        assert!(result.is_err());
405
    }
406
407
    #[test]
408
    fn test_interger_equal() {
409
        let equal: usize = 1;
410
        let not_equal: usize = 0;
411
        let op = Operation::Equal;
412
413
        assert!(
414
            Integer(1).verify(true, &op, 0, equal) && !Integer(1).verify(true, &op, 0, not_equal)
415
        );
416
    }
417
418
    #[test]
419
    fn test_interger_greater_or_equal() {
420
        let less: usize = 0;
421
        let equal: usize = 1;
422
        let greater: usize = 2;
423
424
        let op = Operation::GreaterOrEqual;
425
426
        assert!(
427
            !Integer(1).verify(true, &op, 0, less)
428
                && Integer(1).verify(true, &op, 0, equal)
429
                && Integer(1).verify(true, &op, 0, greater)
430
        );
431
    }
432
433
    #[test]
434
    fn test_string_equal() {
435
        let local = String::from("abc");
436
        let equal = String::from("abc");
437
        let not_equal = String::from("aaa");
438
        let op = Operation::Equal;
439
440
        assert!(
441
            RefString(String::from("abc")).verify(true, &op, &local, &equal)
442
                && !RefString(String::from("abc")).verify(true, &op, &local, &not_equal)
443
        );
444
    }
445
446
    #[test]
447
    fn test_self_equal() {
448
        let local = [1, 2, 3, 4];
449
        let equal = [1, 2, 3, 4];
450
        let not_equal = [1, 2, 3, 4, 5];
451
452
        let op = Operation::Equal;
453
454
        assert!(
455
            !RefLocal.verify(true, &op, &local, &not_equal)
456
                && RefLocal.verify(true, &op, &local, &equal)
457
        );
458
    }
459
460
    #[test]
461
    fn test_self_greater_or_equal() {
462
        let src = [1, 2, 3, 4];
463
        let less = [1, 5, 3, 3];
464
        let equal = [1, 2, 3, 4];
465
        let greater = [1, 1, 3, 5];
466
467
        let op = Operation::GreaterOrEqual;
468
469
        assert!(
470
            !RefLocal.verify(true, &op, &src, &less)
471
                && RefLocal.verify(true, &op, &src, &equal)
472
                && RefLocal.verify(true, &op, &src, &greater)
473
        );
474
475
        let dst = src;
476
        assert!(
477
            RefLocal.verify(false, &op, &dst, &less)
478
                && RefLocal.verify(false, &op, &dst, &equal)
479
                && !RefLocal.verify(false, &op, &dst, &greater)
480
        );
481
    }
482
483
    #[test]
484
    fn test_self_array_equal() {
485
        let src = [1, 2, 3, 4];
486
        let equal = [1, 2, 3, 4];
487
        let unequal = [1, 2, 3, 5];
488
489
        let op = Operation::ArrayEqual;
490
491
        assert!(
492
            !RefLocal.verify(true, &op, &src, &unequal) && RefLocal.verify(true, &op, &src, &equal)
493
        );
494
    }
495
496
    #[test]
497
    fn test_self_array_greater_or_equal() {
498
        let src = [1, 2, 3, 4];
499
        let less1 = [1, 3, 3, 3];
500
        let less2 = [1, 1, 3, 3];
501
        let equal = [1, 2, 3, 4];
502
        let greater = [1, 2, 3, 5];
503
504
        let op = Operation::ArrayGreaterOrEqual;
505
506
        assert!(
507
            !RefLocal.verify(true, &op, &src, &less1)
508
                && !RefLocal.verify(true, &op, &src, &less2)
509
                && RefLocal.verify(true, &op, &src, &equal)
510
                && RefLocal.verify(true, &op, &src, &greater)
511
        );
512
513
        let dst = src;
514
        assert!(
515
            !RefLocal.verify(false, &op, &dst, &less1)
516
                && RefLocal.verify(false, &op, &dst, &less2)
517
                && RefLocal.verify(false, &op, &dst, &equal)
518
                && !RefLocal.verify(false, &op, &dst, &greater)
519
        );
520
    }
521
522
    #[test]
523
    fn test_interrange_inrange() {
524
        let inrange = 2;
525
        let not_inrange = 3;
526
527
        let op = Operation::InRange;
528
529
        assert!(
530
            !IntegerRange(0..3).verify(true, &op, 0, not_inrange)
531
                && IntegerRange(0..3).verify(true, &op, 0, inrange)
532
        );
533
    }
534
535
    #[test]
536
    fn test_array_equal() {
537
        let reference = vec![0x2, 0x60, 0x6a];
538
        let local = &[];
539
        let equal = &[0x2, 0x60, 0x6a];
540
        let greater = &[0x2, 0x60, 0x6c];
541
        let smaller = &[0x2, 0x5f, 0x6a];
542
        let invalid = &[0x2, 0x60, 0x6a, 0x1];
543
        let op = Operation::ArrayEqual;
544
545
        assert!(
546
            Array(reference.clone()).verify(true, &op, local, equal)
547
                && !Array(reference.clone()).verify(true, &op, local, greater)
548
                && !Array(reference.clone()).verify(true, &op, local, smaller)
549
                && !Array(reference.clone()).verify(true, &op, local, invalid)
550
        );
551
    }
552
553
    #[test]
554
    fn test_array_greater_or_equal() {
555
        let reference = vec![0x2, 0x60, 0x6a];
556
        let local = &[];
557
        let equal = &[0x2, 0x60, 0x6a];
558
        let greater = &[0x2, 0x61, 0x6a];
559
        let smaller = &[0x3, 0x60, 0x60];
560
        let op = Operation::ArrayGreaterOrEqual;
561
562
        assert!(
563
            Array(reference.clone()).verify(true, &op, local, equal)
564
                && Array(reference.clone()).verify(true, &op, local, greater)
565
                && !Array(reference.clone()).verify(true, &op, local, smaller)
566
        );
567
    }
568
}