kmip_ttlv/de.rs
1//! High-level Serde based deserialization of TTLV bytes to Rust data types.
2
3use std::{
4 cell::{RefCell, RefMut},
5 cmp::Ordering,
6 collections::HashMap,
7 io::{Cursor, Read},
8 ops::Deref,
9 rc::Rc,
10 str::FromStr,
11};
12
13use serde::{
14 de::{DeserializeOwned, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor},
15 Deserialize, Deserializer,
16};
17
18use crate::traits::AnySyncRead;
19use crate::{
20 error::Error,
21 error::{ErrorKind, ErrorLocation, MalformedTtlvError, Result, SerdeError},
22 types::{
23 self, FieldType, SerializableTtlvType, TtlvBoolean, TtlvDateTime, TtlvEnumeration, TtlvInteger, TtlvLength,
24 TtlvLongInteger, TtlvStateMachine, TtlvStateMachineMode, TtlvTextString,
25 },
26 types::{TtlvBigInteger, TtlvByteString, TtlvTag, TtlvType},
27};
28
29// --- Public interface ------------------------------------------------------------------------------------------------
30
31/// Configuration settings used by the deserializer.
32///
33/// May in future also be used by the serializer.
34#[derive(Debug, Default)]
35pub struct Config {
36 max_bytes: Option<u32>,
37 read_buf: Option<RefCell<Vec<u8>>>,
38}
39
40impl Clone for Config {
41 fn clone(&self) -> Self {
42 Self {
43 max_bytes: self.max_bytes,
44 read_buf: if self.has_buf() {
45 Some(RefCell::new(Vec::new()))
46 } else {
47 None
48 },
49 }
50 }
51}
52
53impl Config {
54 pub fn new() -> Self {
55 Self::default()
56 }
57}
58
59impl Config {
60 /// What, if any, is the configured maximum permitted response size?
61 pub fn max_bytes(&self) -> Option<u32> {
62 self.max_bytes
63 }
64
65 /// Has a persistent read buffer been configured for reading response bytes into?
66 pub fn has_buf(&self) -> bool {
67 self.read_buf.is_some()
68 }
69
70 /// Get mutable access to optional persistent response bytes buffer
71 pub fn read_buf(&self) -> Option<RefMut<Vec<u8>>> {
72 self.read_buf.as_ref().map(|buf| buf.borrow_mut())
73 }
74}
75
76// Builder style interface
77impl Config {
78 /// Specify a maximum number of response bytes to read.
79 ///
80 /// Use this if you are reading data from an untrusted source. If that source then sends a very large response we
81 /// will reject it rather than attempt to read it all and thus avoid possibly running out of memory.
82 pub fn with_max_bytes(self, max_bytes: u32) -> Self {
83 Self {
84 max_bytes: Some(max_bytes),
85 ..self
86 }
87 }
88
89 /// Save the read response bytes into a buffer for use later.
90 ///
91 /// Allocate a persistent buffer that can be used by a reader to store the read response bytes into. This could be
92 /// to avoid allocating a buffer for every response read, or to permit logging or storing or pretty printing of the
93 /// response bytes once they have been read from the source.
94 pub fn with_read_buf(self) -> Self {
95 Self {
96 read_buf: Some(RefCell::new(Vec::new())),
97 ..self
98 }
99 }
100}
101
102/// Read and deserialize bytes from the given slice.
103pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T>
104where
105 T: Deserialize<'de>,
106{
107 let cursor = &mut Cursor::new(bytes);
108 let mut deserializer = TtlvDeserializer::from_slice(cursor);
109 T::deserialize(&mut deserializer)
110}
111
112/// Read and deserialize bytes from the given reader.
113///
114/// Note: Also accepts a mut reference.
115///
116/// Attempting to process a stream whose initial TTL header length value is larger the config max_bytes, if any, will
117/// result in`Error::ResponseSizeExceedsLimit`.
118#[maybe_async::maybe_async]
119pub async fn from_reader<T, R>(mut reader: R, config: &Config) -> Result<T>
120where
121 T: DeserializeOwned,
122 R: AnySyncRead,
123{
124 // When reading from a stream we don't know how many bytes to read until we've read the L of the first TTLV in
125 // the response stream. As the current implementation jumps around in the response bytes while parsing (see
126 // calls to set_position()), and requiring the caller to provider a Seek capable stream would be quite onerous,
127 // and as we're not trying to be super efficient as HSMs are typically quite slow anywa, just read the bytes into a
128 // Vec and then parse it from there. We can't just call read_to_end() because that can cause the response reading to
129 // block if the server doesn't close the connection after writing the response bytes (e.g. PyKMIP behaves this way).
130 // We know from the TTLV specification that the initial TTL bytes must be 8 bytes long (3-byte tag, 1-byte type,
131 // 4-byte length) so we attempt read to this "magic header" from the given stream.
132
133 fn cur_pos(buf_len: u64) -> ErrorLocation {
134 ErrorLocation::from(buf_len)
135 }
136
137 let max_bytes = config.max_bytes();
138
139 // Interior mutability access dance
140 // --------------------------------
141 // The Config object can optionally have its own buffer which we will write the read bytes into. This then allows
142 // the caller to log or save or pretty print those bytes or avoid allocating a new buffer on every read, or
143 // whatever the caller wants to do with them.
144 //
145 // We could take a buffer as an argument but that would complicate the default use case. We could also take a
146 // mutable reference to the Config object but then we'd appear to have the ability to alter the configuration
147 // settings which is not right. So instead we use the interior mutability pattern to get a mutable reference to
148 // just the buffer owned by the Config object, not the entire Config object. However, to write to the Config object
149 // buffer if available or otherwise to a local buffer requires a bit of a dance to get satisfy the Rust compiler
150 // borrow checker.
151 let mut buf_bytes;
152 let mut config_buf = config.read_buf();
153 let mut buf: &mut Vec<u8> = if let Some(ref mut buf) = config_buf {
154 // Use the buffer provided by the Config object.
155 buf
156 } else {
157 // Create and use our own temporary buffer.
158 buf_bytes = Vec::new();
159 &mut buf_bytes
160 };
161
162 // Greedy closure capturing:
163 // -------------------------
164 // Note: In the read_xxx() calls below we take the cursor.position() _before_ the read because otherwise, in Rust
165 // 2018 Edition, the closure captures the cursor causing compilation to fail due to multiple mutable borrows of fhe
166 // cursor. Rust 2021 Edition implements so-called "Disjoint capture in closures" which may eliminate this problem.
167 // See: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html
168
169 // Read the bytes of the first TTL (3 byte tag, 1 byte type, 4 byte len)
170 buf.resize(8, 0);
171 let response_size;
172 let tag;
173 let r#type;
174 {
175 let mut state = TtlvStateMachine::new(TtlvStateMachineMode::Deserializing);
176 reader.read_exact(buf).await.map_err(|err| pinpoint!(err, cur_pos(0)))?;
177
178 // Extract and verify the first T (tag)
179 let mut cursor = Cursor::new(&mut buf);
180 let buf_len = cursor.position();
181 tag = TtlvDeserializer::read_tag(&mut cursor, Some(&mut state))
182 .map_err(|err| pinpoint!(err, cur_pos(buf_len)))?;
183
184 // Extract and verify the second T (type)
185 let buf_len = cursor.position();
186 r#type = TtlvDeserializer::read_type(&mut cursor, Some(&mut state))
187 .map_err(|err| pinpoint!(err, cur_pos(buf_len), tag))?;
188
189 // Extract and verify the L (value length)
190 let buf_len = cursor.position();
191 let additional_len = TtlvDeserializer::read_length(&mut cursor, Some(&mut state))
192 .map_err(|err| pinpoint!(err, cur_pos(buf_len), tag, r#type))?;
193
194 // ------------------------------------------------------------------------------------------
195 // Now read the value bytes of the first TTLV item (i.e. the rest of the entire TTLV message)
196 // ------------------------------------------------------------------------------------------
197
198 // The number of bytes to allocate is determined by the data being read. It could be a gazillion bytes and we'd
199 // panic trying to allocate it. The caller is therefore advised to define an upper bound if the source cannot be
200 // trusted.
201 let buf_len = cursor.position();
202 response_size = buf_len + (additional_len as u64);
203 if let Some(max_bytes) = max_bytes {
204 if response_size > (max_bytes as u64) {
205 let error = ErrorKind::ResponseSizeExceedsLimit(response_size as usize);
206 let location = ErrorLocation::from(cursor).with_tag(tag).with_type(r#type);
207 return Err(Error::pinpoint(error, location));
208 }
209 }
210 }
211
212 // Warning: this will panic if it fails to allocate the requested amount of memory, at least until try_reserve() is
213 // stabilized!
214 buf.resize(response_size as usize, 0);
215 reader
216 .read_exact(&mut buf[8..])
217 .await
218 .map_err(|err| Error::pinpoint(err, ErrorLocation::from(buf.len()).with_tag(tag).with_type(r#type)))?;
219
220 from_slice(buf)
221}
222
223// --- Private implementation details ----------------------------------------------------------------------------------
224
225// Required for impl Deserializer below to use this type, but I don't really want arbitrary strings leaking out of the
226// deserializer as they could leak sensitive data
227impl serde::de::Error for Error {
228 fn custom<T: std::fmt::Display>(msg: T) -> Self {
229 pinpoint!(SerdeError::Other(msg.to_string()), ErrorLocation::unknown())
230 }
231}
232
233impl<'de: 'c, 'c> From<&mut TtlvDeserializer<'de, 'c>> for ErrorLocation {
234 fn from(de: &mut TtlvDeserializer) -> Self {
235 de.location()
236 }
237}
238
239impl<'de: 'c, 'c> From<&TtlvDeserializer<'de, 'c>> for ErrorLocation {
240 fn from(de: &TtlvDeserializer) -> Self {
241 de.location()
242 }
243}
244
245trait ContextualErrorSupport {
246 fn pos(&self) -> u64;
247}
248
249pub(crate) struct TtlvDeserializer<'de: 'c, 'c> {
250 src: &'c mut Cursor<&'de [u8]>,
251
252 state: Rc<RefCell<TtlvStateMachine>>,
253
254 // for container/group types (map, seq)
255 #[allow(dead_code)]
256 group_start: u64,
257 group_tag: Option<TtlvTag>,
258 group_type: Option<TtlvType>,
259 group_end: Option<u64>,
260 group_fields: &'static [&'static str], // optional field handling: expected fields to compare to actual fields
261 group_item_count: usize, // optional field handling: index into the group_fields array
262 group_homogenous: bool, // sequence/map field handling: are all items in the group of the same type?
263
264 // for the current field being parsed
265 item_start: u64, // optional field handling: point to return to if field is missing
266 item_tag: Option<TtlvTag>,
267 item_type: Option<TtlvType>,
268 item_unexpected: bool, // optional field handling: is this tag wrong for the expected field (and thus is missing?)
269 item_identifier: Option<String>,
270
271 // lookup maps
272 tag_value_store: Rc<RefCell<HashMap<TtlvTag, String>>>,
273 matcher_rule_handlers: [(&'static str, MatcherRuleHandlerFn<'de, 'c>); 3],
274
275 // diagnostic support
276 tag_path: Rc<RefCell<Vec<TtlvTag>>>,
277}
278
279type MatcherRuleHandlerFn<'de, 'c> =
280 fn(&TtlvDeserializer<'de, 'c>, &str, &str) -> std::result::Result<bool, types::Error>;
281
282impl<'de: 'c, 'c> TtlvDeserializer<'de, 'c> {
283 // This is not a global read-only static array as they do not support lifetime specification which is required
284 // by the Self::fn_name references which is in turn required because the handler functions can use arbitrary data
285 // from the current instance of the deserializer. One could argue that the set of matcher fns is fixed and thus we
286 // can concretely specify everything in advance, but I'm not convinced that's really more readable.
287 fn init_matcher_rule_handlers() -> [(&'static str, MatcherRuleHandlerFn<'de, 'c>); 3] {
288 [
289 ("==", Self::handle_matcher_rule_eq),
290 (">=", Self::handle_matcher_rule_ge),
291 ("in", Self::handle_matcher_rule_in),
292 ]
293 }
294
295 pub fn from_slice(cursor: &'c mut Cursor<&'de [u8]>) -> Self {
296 Self {
297 src: cursor,
298 state: Rc::new(RefCell::new(TtlvStateMachine::new(TtlvStateMachineMode::Deserializing))),
299 group_start: 0,
300 group_tag: None,
301 group_type: None,
302 group_end: None,
303 group_fields: &[],
304 group_item_count: 0,
305 group_homogenous: false,
306 item_start: 0,
307 item_tag: None,
308 item_type: None,
309 item_unexpected: false,
310 item_identifier: None,
311 tag_value_store: Rc::new(RefCell::new(HashMap::new())),
312 matcher_rule_handlers: Self::init_matcher_rule_handlers(),
313 tag_path: Rc::new(RefCell::new(Vec::new())),
314 }
315 }
316
317 #[allow(clippy::too_many_arguments)]
318 fn from_cursor(
319 src: &'c mut Cursor<&'de [u8]>,
320 state: Rc<RefCell<TtlvStateMachine>>,
321 group_tag: TtlvTag,
322 group_type: TtlvType,
323 group_end: u64,
324 group_fields: &'static [&'static str],
325 group_homogenous: bool, // are all items in the group the same tag and type?
326 unit_enum_store: Rc<RefCell<HashMap<TtlvTag, String>>>,
327 tag_path: Rc<RefCell<Vec<TtlvTag>>>,
328 ) -> Self {
329 let group_start = src.position();
330 let group_tag = Some(group_tag);
331 let group_type = Some(group_type);
332 let group_end = Some(group_end);
333
334 Self {
335 src,
336 state,
337 group_start,
338 group_tag,
339 group_type,
340 group_end,
341 group_fields,
342 group_item_count: 0,
343 group_homogenous,
344 item_start: group_start,
345 item_tag: None,
346 item_type: None,
347 item_unexpected: false,
348 item_identifier: None,
349 tag_value_store: unit_enum_store,
350 matcher_rule_handlers: Self::init_matcher_rule_handlers(),
351 tag_path,
352 }
353 }
354
355 /// Read a 3-byte TTLV tag into an [TtlvTag].
356 ///
357 /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
358 ///
359 /// Note: Also accepts a mut reference.
360 ///
361 /// # Errors
362 ///
363 /// If this function is unable to read 3 bytes from the given reader an [Error::IoError] will be returned.
364 ///
365 /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
366 pub(crate) fn read_tag<R>(
367 mut src: R,
368 state: Option<&mut TtlvStateMachine>,
369 ) -> std::result::Result<TtlvTag, types::Error>
370 where
371 R: Read,
372 {
373 if let Some(state) = state {
374 state.advance(FieldType::Tag)?;
375 }
376 TtlvTag::read(&mut src)
377 }
378
379 /// Read a 1-byte TTLV type into an [ItemType]
380 ///
381 /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
382 ///
383 /// Note: Also accepts a mut reference.
384 ///
385 /// # Errors
386 ///
387 /// If this function is unable to read 1 byte from the given reader an [Error::IoError] will be returned.
388 ///
389 /// If the read byte is not a valid value according to the KMIP 1.0 TTLV specification or is a type which
390 /// we do not yet support an error will be returned.
391 ///
392 /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
393 pub(crate) fn read_type<R>(
394 mut src: R,
395 state: Option<&mut TtlvStateMachine>,
396 ) -> std::result::Result<TtlvType, types::Error>
397 where
398 R: Read,
399 {
400 if let Some(state) = state {
401 state.advance(FieldType::Type)?;
402 }
403 TtlvType::read(&mut src)
404 }
405
406 /// Read a 4-byte TTLV length into a u32.
407 ///
408 /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
409 ///
410 /// Note: Also accepts a mut reference.
411 ///
412 /// # Errors
413 ///
414 /// If this function is unable to read 4 bytes from the given reader an [Error::IoError] will be returned.
415 ///
416 /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
417 pub(crate) fn read_length<R>(
418 mut src: R,
419 state: Option<&mut TtlvStateMachine>,
420 ) -> std::result::Result<u32, types::Error>
421 where
422 R: Read,
423 {
424 if let Some(state) = state {
425 state.advance(FieldType::Length)?;
426 }
427 TtlvLength::read(&mut src).map(|len| *len)
428 }
429
430 /// Read the next TTLV tag and type header and prepare for full deserialization.
431 ///
432 /// Returns Ok(true) if there is data available, Ok(false) if the end of the current group (TTLV sequence or
433 /// structure) has been reached or an I/O error or `MalformedTtlvError` (e.g. if the tag or type are invalid or if
434 /// the read cursor is past the last byte of the group).
435 fn read_item_key(&mut self, use_group_fields: bool) -> Result<bool> {
436 if let Some(group_end) = self.group_end {
437 match self.pos().cmp(&group_end) {
438 Ordering::Less => {
439 // More bytes to read
440 }
441 Ordering::Equal => {
442 // End of group reached
443 return Ok(false);
444 }
445 Ordering::Greater => {
446 // Error: Read cursor is beyond the end of the current TTLV group
447 let error = MalformedTtlvError::overflow(group_end);
448 let location = self.location();
449 return Err(Error::pinpoint(error, location));
450 }
451 }
452 } else {
453 unreachable!()
454 }
455
456 if use_group_fields {
457 self.item_start = self.group_start;
458 self.item_tag = self.group_tag;
459 self.item_type = self.group_type;
460 } else {
461 self.item_start = self.pos() as u64;
462 self.item_tag = None;
463 self.item_type = None;
464
465 let loc = self.location(); // See the note above about working around greedy closure capturing
466 self.item_tag = Some(
467 Self::read_tag(&mut self.src, Some(&mut self.state.borrow_mut()))
468 .map_err(|err| Error::pinpoint(err, loc))?,
469 );
470
471 let loc = self.location(); // See the note above about working around greedy closure capturing
472 self.item_type = Some(
473 Self::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
474 .map_err(|err| Error::pinpoint(err, loc))?,
475 );
476 }
477
478 // As we are invoked for every field that Serde derive found on the target Rust struct we need to handle the
479 // not just the case where the expected tag is present in the byte stream in the expected position in the
480 // sequence, but also:
481 //
482 // - `Option` fields: these represent fields that may optionally exist in the byte stream, i.e. for a Rust
483 // struct field with `#[serde(rename = "0x123456")]` is the next item tag in the byte stream 0x123456 or
484 // something else (because 0x123456 is correctly missing from the byte stream)? These should be
485 // deserialized as `Some` if present, `None` otherwise.
486 //
487 // - Missing fields; tags that exist in the byte stream but do not have a corresponding field in the Rust
488 // struct. These should be ignored unless `#[serde(deny_unknown_fields)]` has been used.
489 //
490 // - Extra fields: tags that exist in the Rust struct but not in the byte stream. These represent missing
491 // but required data which the absence of which should cause deserialization to fail.
492 //
493 // Serde derive expects that we announce the name of the field that we have encountered in the byte stream,
494 // i.e. that `fn deserialize_identifier()` will invoke `visitor.visit_str()` with the *Rust* field name. Due to
495 // our abuse of `#[serde(rename)]` we can't just announce the TTLV tag hex representation as the *Rust* field
496 // name, the *Rust* field name may be something special like "if 0x123456 in ...". Serde derive will only
497 // accept our deserialized value for the field if we announce the exact same name as the field was assigned in
498 // the Rust struct via `#[serde(rename)])`.
499 //
500 // To know which Rust name to announce as the field identifier we rely on the fact that the KMIP TTLV
501 // specification states that "All fields SHALL appear in the order specified" and that Serde derive earlier
502 // gave us the set of field names in the group when processing of the group stated. We keep track of how many
503 // items we have seen in the group and thus expect that for item N we can assume that Serde derive expects us
504 // to announce the Nth group field name.
505 //
506 // We compare the Nth field name to the tag of the next TTLV item. If N >= M, where N is zero-based and M is
507 // the number of fields that Serde derive communicated to us at the start of the group, we announce the TTLV
508 // tag in hex form as the field name so that something useful appears in the Serde error message if any. By
509 // default Serde will ignore the field value by invoking `fn deserialized_ignored_any()` and we will skip over
510 // the bytes of the TTLV item in the stream as if it were not there. If however `#[serde(deny_unknown_fields)]`
511 // is in use this scenario causes Serde derive to abort deserialization with an error.
512 //
513 // If the read tag doesn't match the expected tag, we record that the item is unexpected and continue. If the
514 // field in the Rust struct is an `Option` Serde derive will then invoke `fn deserialize_option()` at which
515 // point we detect the recorded unexpected flag and return `None` (because there was no item for that tag at
516 // this point (which is the correct position in the Rust struct/TTLV Structure sequence for the item) in the
517 // byte stream.
518
519 self.group_item_count += 1;
520
521 self.item_unexpected = if self.group_fields.is_empty() {
522 // We have no idea which field is expected so this field cannot be unexpected, but we also cannot set the
523 // item identifier to announce for this field (though we might establish an identifier subsequently, e.g.
524 // in the case of selecting the appropriate Rust enum variant).
525 false
526 } else {
527 let field_index = self.group_item_count - 1;
528 let actual_tag_str = &self.item_tag.unwrap().to_string();
529 let expected_tag_str = self
530 .group_fields
531 .get(field_index)
532 .map_or_else(|| actual_tag_str.clone(), |v| v.to_string());
533 self.item_identifier = Some(expected_tag_str.clone());
534 actual_tag_str != &expected_tag_str
535 };
536
537 Ok(true)
538 }
539
540 fn get_start_tag_type(&mut self) -> Result<(u64, TtlvTag, TtlvType)> {
541 let (group_start, group_tag, group_type) = if self.pos() == 0 {
542 // When invoked by Serde via from_slice() there is no prior call to next_key_seed() that reads the tag and
543 // type as we are not visiting a map at that point. Thus we need to read the opening tag and type here.
544 let group_start = self.src.position();
545
546 let loc = self.location(); // See the note above about working around greedy closure capturing
547 let group_tag =
548 Self::read_tag(&mut self.src, Some(&mut self.state.borrow_mut())).map_err(|err| pinpoint!(err, loc))?;
549 self.item_tag = Some(group_tag);
550
551 let loc = self.location(); // See the note above about working around greedy closure capturing
552 let group_type = Self::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
553 .map_err(|err| pinpoint!(err, loc))?;
554 self.item_type = Some(group_type);
555
556 (group_start, group_tag, group_type)
557 } else {
558 // When invoked while visiting a map the opening tag and type of the struct header will have already been
559 // read by next_key_seed() so we don't need to read them here.
560 (self.src.position() - 4, self.item_tag.unwrap(), self.item_type.unwrap())
561 };
562 Ok((group_start, group_tag, group_type))
563 }
564
565 fn prepare_to_descend(&mut self, name: &'static str) -> Result<(u64, TtlvTag, TtlvType, u64)> {
566 let loc = self.location(); // See the note above about working around greedy closure capturing
567 let wanted_tag = TtlvTag::from_str(name).map_err(|err| pinpoint!(err, loc))?;
568
569 let (group_start, group_tag, group_type) = self.get_start_tag_type()?;
570
571 if group_tag != wanted_tag {
572 return Err(pinpoint!(
573 SerdeError::UnexpectedTag {
574 expected: wanted_tag,
575 actual: group_tag
576 },
577 self
578 ));
579 }
580
581 if group_type != TtlvType::Structure {
582 return Err(pinpoint!(
583 MalformedTtlvError::UnexpectedType {
584 expected: TtlvType::Structure,
585 actual: group_type
586 },
587 self
588 ));
589 }
590
591 let loc = self.location(); // See the note above about working around greedy closure capturing
592 let group_len =
593 Self::read_length(&mut self.src, Some(&mut self.state.borrow_mut())).map_err(|err| pinpoint!(err, loc))?;
594 let group_end = self.pos() + (group_len as u64);
595 Ok((group_start, group_tag, group_type, group_end))
596 }
597
598 fn is_variant_applicable(&self, variant: &'static str) -> Result<bool> {
599 // str::split_once() wasn't stablized until Rust 1.52.0 but as we want to be usable by Krill, and Krill
600 // supported Rust >= 1.49.0 at the time of writing, we use our own split_once() implementation.
601 pub fn split_once<'a>(value: &'a str, delimiter: &str) -> Option<(&'a str, &'a str)> {
602 value
603 .find(delimiter)
604 .map(|idx| (&value[..idx], &value[idx + delimiter.len()..]))
605 }
606
607 if let Some(rule) = variant.strip_prefix("if ") {
608 for (op, handler_fn) in &self.matcher_rule_handlers {
609 if let Some((wanted_tag, wanted_val)) = split_once(rule, op) {
610 return handler_fn(self, wanted_tag.trim(), wanted_val.trim()).map_err(|err| pinpoint!(err, self));
611 }
612 }
613
614 return Err(pinpoint!(SerdeError::InvalidVariantMatcherSyntax(variant.into()), self));
615 }
616
617 Ok(false)
618 }
619
620 fn handle_matcher_rule_eq(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
621 if wanted_tag == "type" {
622 // See if wanted_val is a literal string that matches the TTLV type we are currently deserializing
623 // TODO: Add BigInteger and Interval when supported
624 if matches!(
625 (wanted_val, self.item_type.unwrap()),
626 ("Structure", TtlvType::Structure)
627 | ("Integer", TtlvType::Integer)
628 | ("LongInteger", TtlvType::LongInteger)
629 | ("Enumeration", TtlvType::Enumeration)
630 | ("Boolean", TtlvType::Boolean)
631 | ("TextString", TtlvType::TextString)
632 | ("ByteString", TtlvType::ByteString)
633 | ("DateTime", TtlvType::DateTime)
634 ) {
635 return Ok(true);
636 }
637 } else if let Ok(wanted_tag) = TtlvTag::from_str(wanted_tag) {
638 if let Some(seen_enum_val) = self.lookup_tag_value(wanted_tag) {
639 if seen_enum_val == wanted_val {
640 return Ok(true);
641 }
642 }
643 }
644
645 Ok(false)
646 }
647
648 fn handle_matcher_rule_ge(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
649 if let Some(seen_enum_val) = self.tag_value_store.borrow().get(&TtlvTag::from_str(wanted_tag)?) {
650 if TtlvTag::from_str(seen_enum_val)?.deref() >= TtlvTag::from_str(wanted_val)?.deref() {
651 return Ok(true);
652 }
653 }
654
655 Ok(false)
656 }
657
658 fn handle_matcher_rule_in(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
659 let wanted_values = wanted_val.strip_prefix('[').and_then(|v| v.strip_suffix(']'));
660 if let Some(wanted_values) = wanted_values {
661 if let Some(seen_enum_val) = self.tag_value_store.borrow().get(&TtlvTag::from_str(wanted_tag)?) {
662 for wanted_value in wanted_values.split(',') {
663 if *seen_enum_val == wanted_value.trim() {
664 return Ok(true);
665 }
666 }
667 }
668 }
669
670 Ok(false)
671 }
672
673 fn location(&self) -> ErrorLocation {
674 let mut loc = ErrorLocation::at(self.src.position().into()).with_parent_tags(&self.tag_path.borrow());
675
676 if let Some(tag) = self.item_tag {
677 loc = loc.with_tag(tag);
678 }
679
680 if let Some(r#type) = self.item_type {
681 loc = loc.with_type(r#type);
682 }
683
684 loc
685 }
686
687 fn remember_tag_value<T>(&self, tag: TtlvTag, value: T)
688 where
689 String: From<T>,
690 {
691 self.tag_value_store.borrow_mut().insert(tag, value.into());
692 }
693
694 fn lookup_tag_value(&self, tag: TtlvTag) -> Option<String> {
695 self.tag_value_store.borrow().get(&tag).cloned()
696 }
697
698 fn seek_forward(&mut self, num_bytes_to_skip: u32) -> Result<u64> {
699 use std::io::Seek;
700 self.src
701 .seek(std::io::SeekFrom::Current(num_bytes_to_skip as i64))
702 .map_err(|err| pinpoint!(err, self))
703 }
704}
705
706// TODO: remove this
707impl<'de: 'c, 'c> ContextualErrorSupport for TtlvDeserializer<'de, 'c> {
708 fn pos(&self) -> u64 {
709 self.src.position()
710 }
711}
712
713macro_rules! unsupported_type {
714 ($deserialize:ident, $type:ident) => {
715 fn $deserialize<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
716 Err(pinpoint!(
717 SerdeError::UnsupportedRustType(stringify!($type)),
718 self
719 ))
720 }
721 };
722}
723
724impl<'de: 'c, 'c> Deserializer<'de> for &mut TtlvDeserializer<'de, 'c> {
725 type Error = Error;
726
727 /// Deserialize the bytes at the current cursor position to a Rust structure.
728 ///
729 /// The use of a Rust structure by the caller is assumed to signify that the TTLV item should be of TTLV type
730 /// "Structure". E.g. given something like:
731 ///
732 /// ```ignore
733 /// #[derive(Deserialize)]
734 /// #[serde(rename = "0x012345")]
735 /// struct MyStruct {
736 /// a: i32,
737 /// b: MyOtherStruct,
738 /// }
739 /// ```
740 ///
741 /// This function will be invoked with the `name` parameter set to `0x012345` (or `MyStruct` if `rename` were not
742 /// used), with the `fields` parameter set to `['a', 'b']`. Serde requires that we delegate to either `visit_map()`
743 /// or `visit_seq()`. These delegates are responsible for issuing key/value pairs that correspond to the struct
744 /// fields (e.g. `a` and `b` in the example above) being processed by Serde.
745 ///
746 /// For keys serde invokes `deserialize_identifier()` to parse out the field name from the byte stream and pass it
747 /// to `visit_str()`.
748 ///
749 /// For values serde invokes the corresponding trait function in this impl, e.g. `deserialize_i32()`, to
750 /// parse out the TTLV value and pass it to the corresponding visit function such as `visit_i32()`. For
751 /// complex types such as a struct or vec the `deserialize_struct` (i.e. recursion) or `deserialize_seq` will be
752 /// invoked.
753 ///
754 /// We have to be careful to handle correctly the fact that the Rust structure fields are "children" in the TTLV
755 /// byte stream of a TTLV structure, e.g. for the example above the byte stream might contain TTLV bytes like so:
756 ///
757 /// ```text
758 /// TTLVVVVVVVVVVVVVVVVVV <- the TTLV representation of 'MyStruct'
759 /// TTLVVTTLVVVVVVVVVV <- the TTLV representation of 'a' and 'b' within 'MyStruct'
760 /// ```
761 ///
762 /// Furthermore, field order in TTLV matters. We remember the given fields and if we encounter a field other than
763 /// the one that we expect we flag it as unexpected. We can't immediately reject it because it could be that the
764 /// caller wrapped the type to deserialize to in a Rust `Option` indicating that the TTLV item is optional. If when
765 /// Serde asks us to process the value we will raise an error if we are not asked to process an `Option`.
766 fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
767 where
768 V: Visitor<'de>,
769 {
770 let (_, group_tag, group_type, group_end) = self.prepare_to_descend(name)?;
771
772 let mut struct_cursor = self.src.clone();
773
774 self.tag_path.borrow_mut().push(group_tag);
775
776 let descendent_parser = TtlvDeserializer::from_cursor(
777 &mut struct_cursor,
778 self.state.clone(),
779 group_tag,
780 group_type,
781 group_end,
782 fields,
783 false, // struct member fields can have different tags and types
784 self.tag_value_store.clone(),
785 self.tag_path.clone(),
786 );
787
788 let r = visitor.visit_map(descendent_parser); // jumps to impl MapAccess below
789
790 // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
791 self.src.set_position(struct_cursor.position());
792
793 match r {
794 Ok(_) => {
795 self.tag_path.borrow_mut().pop();
796 r
797 }
798 Err(err) => {
799 // Errors can be raised directly by Serde Derive, e.g. SerdeError::Other("missing field"), which
800 // necessarily have ErrorLocation::is_unknown() as Serde Derive is not aware of our ErrorLocation type.
801 // When that happens, this is the first opportunity after calling `visitor.visit_map()` that we have to
802 // add the missing location data. However, if the error _was_ raised by our code and not by Serde
803 // Derive it probably already has location details. Therefore we "merge" the current location into the
804 // error so that only missing details are added if needed as the existing location details may more
805 // point more accurately to the source of the problem than we are able to indicate here (we don't know
806 // where in the `visit_map()` process the issue occured, on which field and at which byte, we just use
807 // the current cursor position and hope that is good enough).
808 let (kind, loc) = err.into_inner();
809 let new_loc = loc.merge(self.location());
810 Err(Error::new(kind, new_loc))
811 }
812 }
813 }
814
815 /// Deserialize the bytes at the current cursor position to a Rust struct with a single field.
816 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
817 where
818 V: Visitor<'de>,
819 {
820 visitor.visit_newtype_struct(self) // jumps to to the appropriate deserializer fn such as deserialize_string()
821 }
822
823 /// Deserialize the bytes at the current cursor position to a Rust vector.
824 ///
825 /// The use of a Rust vector by the caller is assumed to signify that the next items in the TTLV byte stream will
826 /// represent an instance of "MAY be repeated" in the KMIP 1.0 spec. E.g. for [section 4.24 Query of the KMIP 1.0 spec](https://docs.oasis-open.org/kmip/spec/v1.0/os/kmip-spec-1.0-os.html#_Toc262581232)
827 /// for the Query operation response, one could represent the response like so:
828 ///
829 /// ```ignore
830 /// struct QueryResponsePayload { // OBJECT REQUIRED
831 /// operations: Vec<Operation>, // Operation No, MAY be repeated
832 /// object_types: Vec<ObjectType>, // Object Type No, MAY be repeated
833 /// ...
834 /// }
835 /// ```
836 ///
837 /// _(the inline comments quote the relevant parts of the KMIP 1.0 spec)_
838 ///
839 /// The KMIP 1.0 spec does not define the terminating conditions for a field that "MAY be repeated. This
840 /// deserializer assumes that the sequence is limited by the L_ength of the TTLV item that contains it and that to
841 /// be considered part of a "MAY be repeated" sequence the TTLV item must have the same tag and type as the previous
842 /// items. Otherwise two adjacent "MAY be repeated" sequences within the same parent TTLV "Structure" would not have
843 /// a clear boundary indicating when one sequence ends and the other starts. For example, checking the tag and type
844 /// are needed to know whether the next TTLV item in the QueryResponsePayload example above is another item in the
845 /// operations vector or is the first item in the object_types vector.
846 ///
847 /// When deserializing a structure the initial TTL is a sort of header for the structure, with the structure field
848 /// values following the header as individual TTLV Items. When deserializing a sequence however the initial TTL is
849 /// not separate to but rather belongs to the first item in the sequence.
850 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
851 where
852 V: Visitor<'de>,
853 {
854 let seq_tag = self.item_tag.unwrap();
855 let seq_type = self.item_type.unwrap();
856 let seq_end = self.group_end.unwrap();
857
858 let mut seq_cursor = self.src.clone();
859
860 let descendent_parser = TtlvDeserializer::from_cursor(
861 &mut seq_cursor,
862 self.state.clone(),
863 seq_tag,
864 seq_type,
865 seq_end,
866 &[],
867 true, // sequence fields must all have the same tag and type
868 self.tag_value_store.clone(),
869 self.tag_path.clone(),
870 );
871
872 let r = visitor.visit_seq(descendent_parser); // jumps to impl SeqAccess below
873
874 // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
875 self.src.set_position(seq_cursor.position());
876
877 r
878 }
879
880 /// Deserialize the bytes at the current cursor position to a Rust Option.
881 ///
882 /// The TTLV format has no explicit support for optional items, though a client and server may agree that it is okay
883 /// for a particular point in the TTLV byte stream to optionally contain a particular TTLV item. For example the
884 /// KMIP 1.0 spec labels some response fields as NOT required i.e. optional. To handle such cases the caller can use
885 /// the Rust Option type in the datatype being deserialized into. As TTLV has no explicit mechanism to indicate a
886 /// NULL or missing value, the caller MUST treat missing fields that deserialize to an `Option` as `None`. For
887 /// example:
888 ///
889 /// ```ignore
890 /// #[derive(Deserialize)]
891 /// #[serde(rename = "0x42000F")]
892 /// pub struct BatchItem {
893 /// #[serde(default)]
894 /// pub operation: Option<Operation>,
895 /// ...
896 /// }
897 /// ```
898 ///
899 /// Here we see a KMIP BatchItem response structure with an optional field and the use of `#[serde(default)]` to set
900 /// the member field to `None` if the corresponding TTLV item is not found while deserializing.
901 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
902 where
903 V: Visitor<'de>,
904 {
905 // The tag and type have already been read, now we are handling the value. How can we know that this item is
906 // NOT the one that was intended to fill the Option and thus the item is missing and the Option should be
907 // populated with None. This can happen e.g. in the case of a KMIP response the response batch item structure
908 // 0x42000F has several optional member fields including the operation code field 0x42005C. The operation code
909 // field is only required to be present in the response if it was present in the request. The order of fields
910 // in a KMIP structure is also required to match that of the spec and the operation code field is the first
911 // item in the response batch item structure.
912 //
913 // Thus if we define a Rust struct for the response batch item TTLV structure the first member must be an
914 // optional operation code, but the first batch item structure member field present in the TTLV response might
915 // be another response batch item field such as result status 0x42007F. We handle this by detecting the
916 // mismatch between Rust field name (i.e. TTLV tag) and the actual tag code found in the TTLV bytes. If they do
917 // not match and the Rust field was of type Option then we respond as if the field value was read and the
918 // Option should be set to None, but we reset the read cursor in the TTLV byte stream so that we will read this
919 // "wrong" tag again as it should match one of the as yet unprocessed member fields in the Rust struct.
920 //
921 // Finally we have to reset the state machine as we just read a tag and type and the next TTLV fields should be
922 // the length and value, but we are resetting the read cursor to point at the tag again.
923
924 // Is this the field we expected at this point?
925 if self.item_unexpected {
926 // This isn't the item that the caller expected but they indicated that the expected item was optional.
927 // Report back that the optional item was not found and rewind the read cursor so that we will visit this
928 // TTLV tag again.
929 self.src.set_position(self.item_start);
930 // Reset the state machine to expect a tag as it's currently expecting a value but should expect a tag.
931 self.state.borrow_mut().reset();
932 visitor.visit_none()
933 } else {
934 visitor.visit_some(self)
935 }
936 }
937
938 /// Deserialize the bytes at the current cursor position to a Rust unit-like enum variant or struct enum variant.
939 ///
940 /// # Unit-like enum variants
941 ///
942 /// Rust enum variants can be unit-like or can have data attached to them. The unit-like form should be used when
943 /// the TTLV bytes being deserialized are of type "Enumeration". Serde will use the deserialized unsigned 32-bit
944 /// value to select a variant with matching name. By using the serde-derive rename feature we can associate each
945 /// enum variant with a single TTLV "Enumeration" value. For example one could define the first few values of the
946 /// KMIP "Operation" Enumeration like so:
947 ///
948 /// ```ignore
949 /// #[derive(Deserialize, Serialize, Display)]
950 /// #[serde(rename = "0x42005C")]
951 /// #[non_exhaustive]
952 /// pub enum Operation {
953 /// #[serde(rename = "0x00000001")]
954 /// Create,
955 ///
956 /// #[serde(rename = "0x00000002")]
957 /// CreateKeyPair,
958 ///
959 /// #[serde(rename = "0x00000003")]
960 /// Register,
961 /// ```
962 ///
963 /// These enum variants are referred to as unit-like as they have no associated data, i.e. the variants have the
964 /// form `Create` rather than `Create(...some associated data...)`.
965 ///
966 /// The TTLV byte sequence `42005C05000000040000000200000000` will be deserialized as tag `0x42005C`, type 0x05
967 /// (Enumeration), value length 4 (bytes) and a 4-byte 0x00000002 value with 4 bytes of padding. Serde will be
968 /// notified that the callers identifier with name "0x00000002" should have the value `Operation::CreateKeyPair`.
969 ///
970 /// # Struct enum variants
971 ///
972 /// By using an enum with struct variants the caller signals to the deserializer that it expects the TTLV byte
973 /// stream to contain a TTLV "Structure" item that can be deserialized into one of the variant structs, but which
974 /// one? For this to work we must also give the deserializer a way of determining from the data deserialized so far
975 /// which of the variants is represented by the TTLV byte stream. We do this by using a serde "name" with a special
976 /// syntax of the form `if A==B`.
977 ///
978 /// Let's see this in action using the variable KMIP response payload structure layout as an example where the
979 /// payload structure to deserialize is indicated by the KMIP Operation enum value that appears earlier in the TTLV
980 /// byte stream:
981 ///
982 /// First we define a struct that contains the variable payload as a member field:
983 ///
984 /// ```ignore
985 /// #[derive(Deserialize)]
986 /// #[serde(rename = "0x42000F")]
987 /// pub struct BatchItem {
988 /// pub operation: Option<Operation>,
989 /// pub payload: Option<ResponsePayload>,
990 /// }
991 /// ```
992 ///
993 /// Then we define the variable payload type as an enum whose variants have different Rust structures attached to
994 /// them. We also signal to the deserializer how each variant is selected by some other value in the TTLV byte
995 /// stream:
996 ///
997 /// ```ignore
998 /// #[derive(Deserialize)]
999 /// #[serde(rename = "0x42007C")]
1000 /// #[non_exhaustive]
1001 /// pub enum ResponsePayload {
1002 /// #[serde(rename = "if 0x42005C==0x00000001")]
1003 /// Create(CreateResponsePayload),
1004 ///
1005 /// #[serde(rename = "if 0x42005C==0x00000002")]
1006 /// CreateKeyPair(CreateKeyPairResponsePayload),
1007 ///
1008 /// #[serde(rename = "if 0x42005C==0x00000003")]
1009 /// Register(RegisterResponsePayload),
1010 /// }
1011 /// ```
1012 ///
1013 /// Where `CreateResponsePayload`, `CreateKeyPairResponsePayload` and `RegisterResponsePayload` are Rust structs
1014 /// defined elsewhere.
1015 ///
1016 /// The special name syntax `if A==B` is used here to select the correct variant by matching against the value of
1017 /// another tag, "Operation" in this case, seen earlier in the TTLV byte stream. A TTLV byte sequence of the form
1018 /// `42000F01LLLLLLLL42005C0500000004000000020000000042007C01LLLLLLLLV...` would be deserialized as operation code
1019 /// 0x00000002 indicating that the payload is of type `CreateKeyPairResponsePayload`.
1020 ///
1021 /// The if syntax currently only supports matching against the value of earlier seen enum or string TTLV items that
1022 /// are looked up by their tag.
1023 fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> Result<V::Value>
1024 where
1025 V: Visitor<'de>,
1026 {
1027 // We don't know which type of enum the caller is deserializing into nor without guidance do we even know which
1028 // variant to announce to Serde that we are populating. We assume that the caller knows whether to expect a
1029 // structure or a single integer value in the TTLV byte stream at this point and that they therefore correctly
1030 // specified a tuple/tuple-struct enum variant or a unit-like variant as the datatype being deserialized into.
1031 //
1032 // We can only do two things:
1033 // 1. Deserialize the type of TTLV item that we find at this point in the byte stream.
1034 //
1035 // 2. Announce to serde either the TTLV tag as the variant name, or if the enum name is in the special form
1036 // "if A==B" attempt to see if the value of previously seen tag A is B and if so we then announce the
1037 // "if A==B" variant name as the chosen variant.
1038 //
1039 // When matching against previously seen tag values the match we find is used to tell Serde which enum variant
1040 // to deserialie into. This is the only case where we support an enum within an enum in the Rust code structure,
1041 // as TTLV doesn't support such nesting of enum values, that is we match against the name (or rename) of the
1042 // variant in an outer enum but the TTLV enum value that we read is used to select the variant of an inner enum.
1043 //
1044 // The concrete KMIP use case for such nested enums is when the response includes an Attribute Value whose tag
1045 // cannot tell us which Rust enum variant to deserialize into as it is always the same (0x42000B) so instead we
1046 // want to use the Attribute Name tag (0x42000A) string value seen earlier to select the Rust variant to
1047 // deserialize into, but that variant is itself an enum (e.g. AttributeValue::State(State)) and the actual TTLV
1048 // enum value read selects the variant of this "inner" State enum that will be deserialized into (e.g.
1049 // State::PreActive).
1050
1051 self.item_identifier = None;
1052
1053 // Check each enum variant name to see if it is of the form "if enum_tag==enum_val" and if so extract
1054 // enum_tag and enum_value:
1055 for v in variants {
1056 if self.is_variant_applicable(v)? {
1057 self.item_identifier = Some(v.to_string());
1058 break;
1059 }
1060 }
1061
1062 // 1: Deserialize according to the TTLV item type:
1063 match self.item_type {
1064 Some(TtlvType::Enumeration) | Some(TtlvType::Integer) => {
1065 // 2: Read a TTLV enumeration from the byte stream and announce the read value as the enum variant name.
1066 // If we are selecting an enum variant based on a special "if" string then item_identifier will be
1067 // Some(xxx) where xxx will NOT match the TTLV value that is waiting to be read, instead that will
1068 // match an inner enum variant so we read the TTLV value when we visit this function again deeper in
1069 // the call hierarchy. This enables handling of cases such as `AttributeName` string field that
1070 // indicates the enum variant represented by the `AttributeValue`.
1071 if self.item_identifier.is_none() {
1072 let loc = self.location(); // See the note above about working around greedy closure capturing
1073 self.state
1074 .borrow_mut()
1075 .advance(FieldType::LengthAndValue)
1076 .map_err(|err| pinpoint!(err, loc.clone()))?;
1077 let enum_val = TtlvEnumeration::read(self.src).map_err(|err| pinpoint!(err, loc))?;
1078 let enum_hex = format!("0x{}", hex::encode_upper(enum_val.to_be_bytes()));
1079
1080 // Insert or replace the last value seen for this enum in our enum value lookup table
1081 self.remember_tag_value(self.item_tag.unwrap(), &enum_hex);
1082
1083 self.item_identifier = Some(enum_hex);
1084 }
1085
1086 visitor.visit_enum(&mut *self) // jumps to impl EnumAccess (ending at unit_variant()) below
1087 }
1088 Some(item_type) => {
1089 // "simple" enums, i.e. TTLV integer or TTLV enumeration values in the byte stream, are handled by the
1090 // case above.
1091 //
1092 // This case is for handling non-enum non-int TTLV types in the byte stream which are next to deserialize
1093 // because they match a "complex" enum variant, i.e. a tuple or struct variant that has an associated type
1094 // or types whose values are now attempintg to deserialize.
1095 //
1096 // As we can't read an enum/int value from the byte stream and use that as the item_identifier to announce
1097 // to serde we can't select the right variant. So instead we is_variant_applicable() to have been used
1098 // successfully above to grab a variant name to announce here. So if we get here and self.item_identifier
1099 // is not set then we can't announce a variant and Serde will fail to deserialize. That's fine, users
1100 // shouldn't be trying to deserialize non-TTLV-enums into Rust enums directly!
1101
1102 // This logic can handle cases such as a previously seen `BatchItem.operation` enum field whose value was
1103 // e.g. 0x00000005 which we stored in the value_store map against the tag id of the `BatchItem.operation`
1104 // field and can now use that to select a variant by naming the variant
1105 // "if <prev_tag_id> == <this_variant_id>".
1106
1107 // If we couldn't work out the correct variant name to announce to serde, don't bother going further as
1108 // that will result in `deserialize_identfier()` below calling `visitor.visit_str(identifier)` which will
1109 // then raise a `SerdeError::Other("unknown variant")` error. That isn't terrible, but it's better to
1110 // raise a `SerdeError::UnexpectedType` error here instead as really we are being asked to deserialize a
1111 // non-enum TTLV item into a Rust enum which is a type expectation mismatch.
1112 if self.item_identifier.is_none() {
1113 let error = SerdeError::UnexpectedType {
1114 expected: TtlvType::Enumeration,
1115 actual: item_type,
1116 };
1117 Err(pinpoint!(error, self))
1118 } else {
1119 visitor.visit_enum(&mut *self) // jumps to impl EnumAccess below
1120 }
1121 }
1122 None => {
1123 let error = SerdeError::Other(format!("TTLV item type for enum '{}' has not yet been read", name));
1124 Err(pinpoint!(error, self))
1125 }
1126 }
1127 }
1128
1129 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
1130 where
1131 V: Visitor<'de>,
1132 {
1133 if let Some(identifier) = &self.item_identifier {
1134 visitor.visit_str(identifier)
1135 } else {
1136 Err(pinpoint!(SerdeError::MissingIdentifier, self))
1137 }
1138 }
1139
1140 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
1141 where
1142 V: Visitor<'de>,
1143 {
1144 let loc = self.location(); // See the note above about working around greedy closure capturing
1145 self.state
1146 .borrow_mut()
1147 .advance(FieldType::LengthAndValue)
1148 .map_err(|err| pinpoint!(err, loc))?;
1149 match self.item_type {
1150 Some(TtlvType::Integer) | None => {
1151 let v = TtlvInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1152 visitor.visit_i32(*v)
1153 }
1154 Some(other_type) => {
1155 let error = SerdeError::UnexpectedType {
1156 expected: TtlvType::Integer,
1157 actual: other_type,
1158 };
1159 Err(pinpoint!(error, self))
1160 }
1161 }
1162 }
1163
1164 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
1165 where
1166 V: Visitor<'de>,
1167 {
1168 let loc = self.location(); // See the note above about working around greedy closure capturing
1169 self.state
1170 .borrow_mut()
1171 .advance(FieldType::LengthAndValue)
1172 .map_err(|err| pinpoint!(err, loc))?;
1173 match self.item_type {
1174 Some(TtlvType::LongInteger) | None => {
1175 let v = TtlvLongInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1176 visitor.visit_i64(*v)
1177 }
1178 Some(TtlvType::DateTime) => {
1179 let v = TtlvDateTime::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1180 visitor.visit_i64(*v)
1181 }
1182 Some(other_type) => {
1183 let error = SerdeError::UnexpectedType {
1184 expected: TtlvType::LongInteger,
1185 actual: other_type,
1186 };
1187 Err(pinpoint!(error, self))
1188 }
1189 }
1190 }
1191
1192 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
1193 where
1194 V: Visitor<'de>,
1195 {
1196 let loc = self.location(); // See the note above about working around greedy closure capturing
1197 self.state
1198 .borrow_mut()
1199 .advance(FieldType::LengthAndValue)
1200 .map_err(|err| pinpoint!(err, loc))?;
1201 match self.item_type {
1202 Some(TtlvType::Boolean) | None => {
1203 let v = TtlvBoolean::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1204 visitor.visit_bool(*v)
1205 }
1206 Some(other_type) => {
1207 let error = SerdeError::UnexpectedType {
1208 expected: TtlvType::Boolean,
1209 actual: other_type,
1210 };
1211 Err(pinpoint!(error, self))
1212 }
1213 }
1214 }
1215
1216 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
1217 where
1218 V: Visitor<'de>,
1219 {
1220 let loc = self.location(); // See the note above about working around greedy closure capturing
1221 self.state
1222 .borrow_mut()
1223 .advance(FieldType::LengthAndValue)
1224 .map_err(|err| pinpoint!(err, loc))?;
1225 match self.item_type {
1226 Some(TtlvType::TextString) | None => {
1227 let str = TtlvTextString::read(&mut self.src).map_err(|err| pinpoint!(err, self.location()))?;
1228
1229 // Insert or replace the last value seen for this tag in our value lookup table
1230 self.remember_tag_value(self.item_tag.unwrap(), str.0.clone());
1231
1232 visitor.visit_string(str.0)
1233 }
1234 Some(other_type) => {
1235 let error = SerdeError::UnexpectedType {
1236 expected: TtlvType::TextString,
1237 actual: other_type,
1238 };
1239 Err(pinpoint!(error, self))
1240 }
1241 }
1242 }
1243
1244 /// Use #[serde(with = "serde_bytes")] to direct Serde to this deserializer function for type Vec<u8>.
1245 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
1246 where
1247 V: Visitor<'de>,
1248 {
1249 let loc = self.location(); // See the note above about working around greedy closure capturing
1250 self.state
1251 .borrow_mut()
1252 .advance(FieldType::LengthAndValue)
1253 .map_err(|err| pinpoint!(err, loc))?;
1254 match self.item_type {
1255 Some(TtlvType::ByteString) | Some(TtlvType::BigInteger) | None => {
1256 let v = TtlvByteString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1257 visitor.visit_byte_buf(v.0)
1258 }
1259 Some(other_type) => {
1260 let error = SerdeError::UnexpectedType {
1261 expected: TtlvType::ByteString,
1262 actual: other_type,
1263 };
1264 Err(pinpoint!(error, self))
1265 }
1266 }
1267 }
1268
1269 /// Skip over the current TTLV item.
1270 ///
1271 /// When `#[serde(deny_unknown_fields)]` is not used this function is invoked by Serde derive to have us skip over
1272 /// a TTLV item for which no corresponding Rust struct field exists to deserialize it into.
1273 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
1274 where
1275 V: Visitor<'de>,
1276 {
1277 // Skip over the TTLV item. We can't just read the length and skip it because the meaning of the length is TTLV
1278 // type dependent. For some types it is the entire byte size of the TTLV item, for others it is the length of
1279 // the TTLV item value excluding padding. For TTLV Structures skip the whole structure content. For other types
1280 // deserialize them but discard the deserialized value.
1281
1282 if matches!(self.item_type.unwrap(), TtlvType::Structure) {
1283 // We're going to read the structure length and then skip it without reading the value
1284 // Reading the length advances the state machine past the length but not past the value
1285 // so we have to do that manually.
1286
1287 // Use the TTLV item length to skip the structure.
1288 let num_bytes_to_skip = TtlvDeserializer::read_length(&mut self.src, Some(&mut self.state.borrow_mut()))
1289 .map_err(|err| pinpoint!(err, self.location()))?;
1290
1291 // Skip the value bytes
1292 self.seek_forward(num_bytes_to_skip)?;
1293
1294 // Tell the state machine that we're finished reading this TTLV item
1295 self.state.borrow_mut().reset();
1296 } else {
1297 // We're going to read the value length, read the value and discard the value, all without involving
1298 // the state machine, so tell it what we are about to do.
1299 // TODO: pass the state machine to the ::read() functions instead and have them update it.
1300 let loc = self.location(); // See the note above about working around greedy closure capturing
1301 self.state
1302 .borrow_mut()
1303 .advance(FieldType::LengthAndValue)
1304 .map_err(|err| pinpoint!(err, loc))?;
1305
1306 match self.item_type.unwrap() {
1307 TtlvType::Structure => {
1308 // We handled this case above
1309 unreachable!()
1310 }
1311 TtlvType::Integer => {
1312 TtlvInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1313 }
1314 TtlvType::LongInteger => {
1315 TtlvLongInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1316 }
1317 TtlvType::BigInteger => {
1318 TtlvBigInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1319 }
1320 TtlvType::Enumeration => {
1321 TtlvEnumeration::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1322 }
1323 TtlvType::Boolean => {
1324 TtlvBoolean::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1325 }
1326 TtlvType::TextString => {
1327 TtlvTextString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1328 }
1329 TtlvType::ByteString => {
1330 TtlvByteString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1331 }
1332 TtlvType::DateTime => {
1333 TtlvDateTime::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1334 }
1335 }
1336 }
1337
1338 // Any visitor fn can be invoked here, they all internally return Ok(IgnoredAny).
1339 visitor.visit_none()
1340 }
1341
1342 // dummy implementations of unsupported types so that we can give back a more useful error message than when using
1343 // `forward_to_deserialize_any()` as the latter doesn't make available the type currently being deserialized into.
1344
1345 unsupported_type!(deserialize_u8, u8);
1346 unsupported_type!(deserialize_u16, u16);
1347 unsupported_type!(deserialize_u32, u32);
1348 unsupported_type!(deserialize_u64, u64);
1349 unsupported_type!(deserialize_i8, i8);
1350 unsupported_type!(deserialize_i16, i16);
1351 unsupported_type!(deserialize_f32, f32);
1352 unsupported_type!(deserialize_f64, f64);
1353 unsupported_type!(deserialize_char, char);
1354 unsupported_type!(deserialize_str, str);
1355 unsupported_type!(deserialize_map, map);
1356 unsupported_type!(deserialize_bytes, bytes);
1357 unsupported_type!(deserialize_unit, unit);
1358
1359 fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
1360 where
1361 V: Visitor<'de>,
1362 {
1363 Err(pinpoint!(SerdeError::UnsupportedRustType("unit struct"), self))
1364 }
1365
1366 fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value>
1367 where
1368 V: Visitor<'de>,
1369 {
1370 Err(pinpoint!(SerdeError::UnsupportedRustType("tuple struct"), self))
1371 }
1372
1373 fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
1374 where
1375 V: Visitor<'de>,
1376 {
1377 Err(pinpoint!(SerdeError::UnsupportedRustType("tuple"), self))
1378 }
1379
1380 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
1381 where
1382 V: Visitor<'de>,
1383 {
1384 Err(pinpoint!(SerdeError::UnsupportedRustType("any"), self))
1385 }
1386}
1387
1388// Deserialize structure members
1389impl<'de: 'c, 'c> MapAccess<'de> for TtlvDeserializer<'de, 'c> {
1390 type Error = Error;
1391
1392 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1393 where
1394 K: serde::de::DeserializeSeed<'de>,
1395 {
1396 if self.read_item_key(false)? {
1397 seed.deserialize(self).map(Some) // jumps to deserialize_identifier() above
1398 } else {
1399 // The end of the group was reached
1400 Ok(None)
1401 }
1402 }
1403
1404 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1405 where
1406 V: serde::de::DeserializeSeed<'de>,
1407 {
1408 seed.deserialize(self) // jumps to deserialize_xxx() in impl Deserializer above
1409 }
1410}
1411
1412// Deserialize a Vec of one type/tag
1413impl<'de: 'c, 'c> SeqAccess<'de> for TtlvDeserializer<'de, 'c> {
1414 type Error = Error;
1415
1416 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
1417 where
1418 T: serde::de::DeserializeSeed<'de>,
1419 {
1420 if !self.read_item_key(self.group_item_count == 0)? {
1421 // The end of the containing group was reached
1422 Ok(None)
1423 } else if self.group_homogenous && (self.item_tag != self.group_tag || self.item_type != self.group_type) {
1424 // The next tag is not part of the sequence.
1425 // Walk the cursor back before the tag because we didn't consume it.
1426 self.src.set_position(self.item_start);
1427 // And reset the state machine to expect a tag again
1428 self.state.borrow_mut().reset();
1429 Ok(None)
1430 } else {
1431 // The tag and type match that of the first item in the sequence, process this element.
1432 seed.deserialize(self).map(Some) // jumps to deserialize_identifier() above
1433 }
1434 }
1435}
1436
1437// Deserialize an enum
1438impl<'de: 'c, 'c> EnumAccess<'de> for &mut TtlvDeserializer<'de, 'c> {
1439 type Error = Error;
1440 type Variant = Self;
1441
1442 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
1443 where
1444 V: serde::de::DeserializeSeed<'de>,
1445 {
1446 let val = seed.deserialize(&mut *self)?; // jumps to deserialize_identifier() above
1447 Ok((val, self)) // jumps to VariantAccess below
1448 }
1449}
1450
1451// Deserialize a variant of an enum
1452impl<'de: 'c, 'c> VariantAccess<'de> for &mut TtlvDeserializer<'de, 'c> {
1453 type Error = Error;
1454
1455 fn unit_variant(self) -> Result<()> {
1456 Ok(())
1457 }
1458
1459 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
1460 where
1461 T: serde::de::DeserializeSeed<'de>,
1462 {
1463 seed.deserialize(self)
1464 }
1465
1466 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
1467 where
1468 V: Visitor<'de>,
1469 {
1470 // The caller has provided a Rust enum variant in tuple form, i.e. SomeEnum(a, b, c), and expects us to
1471 // deserialize the right number of items to match those fields.
1472 let loc = self.location(); // See the note above about working around greedy closure capturing
1473 let seq_len = TtlvDeserializer::read_length(&mut self.src, Some(&mut self.state.borrow_mut()))
1474 .map_err(|err| pinpoint!(err, loc))?;
1475 let seq_start = self.pos() as u64;
1476 let seq_end = seq_start + (seq_len as u64);
1477
1478 let loc = self.location(); // See the note above about working around greedy closure capturing
1479 let seq_tag = TtlvDeserializer::read_tag(&mut self.src, Some(&mut self.state.borrow_mut()))
1480 .map_err(|err| pinpoint!(err, loc))?;
1481 self.item_tag = Some(seq_tag);
1482
1483 let loc = self.location(); // See the note above about working around greedy closure capturing
1484 let seq_type = TtlvDeserializer::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
1485 .map_err(|err| pinpoint!(err, loc))?;
1486 self.item_type = Some(seq_type);
1487
1488 let mut seq_cursor = self.src.clone();
1489
1490 let descendent_parser = TtlvDeserializer::from_cursor(
1491 &mut seq_cursor,
1492 self.state.clone(),
1493 seq_tag,
1494 seq_type,
1495 seq_end,
1496 &[],
1497 false, // don't require all fields in the sequence to be of the same tag and type
1498 self.tag_value_store.clone(),
1499 self.tag_path.clone(),
1500 );
1501
1502 let r = visitor.visit_seq(descendent_parser); // jumps to impl SeqAccess below
1503
1504 // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
1505 self.src.set_position(seq_cursor.position());
1506
1507 r
1508 }
1509
1510 fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
1511 where
1512 V: Visitor<'de>,
1513 {
1514 Err(pinpoint!(SerdeError::UnsupportedRustType("struct variant"), self))
1515 }
1516}