1use crate::error::{Error, Result};
10use crate::tag::Tag;
11use crate::value::Value;
12use crate::{element_type as et, tag_control as tc};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum ContainerKind {
19 Structure,
21 Array,
23 List,
25}
26
27#[derive(Debug, Clone, PartialEq)]
29#[non_exhaustive]
30pub enum Element {
31 Scalar {
33 tag: Tag,
35 value: Value,
37 },
38
39 ContainerStart {
43 tag: Tag,
45 kind: ContainerKind,
47 },
48
49 ContainerEnd,
51}
52
53pub const MAX_DEPTH: usize = 32;
57
58pub const DEFAULT_ELEMENT_BUDGET: usize = 1 << 20;
74
75pub struct TlvReader<'a> {
77 bytes: &'a [u8],
78 pos: usize,
79 depth: usize,
80 element_budget: usize,
89}
90
91impl<'a> TlvReader<'a> {
92 pub fn new(bytes: &'a [u8]) -> Self {
95 Self {
96 bytes,
97 pos: 0,
98 depth: 0,
99 element_budget: DEFAULT_ELEMENT_BUDGET,
100 }
101 }
102
103 pub fn with_element_budget(bytes: &'a [u8], budget: usize) -> Self {
111 Self {
112 bytes,
113 pos: 0,
114 depth: 0,
115 element_budget: budget,
116 }
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.pos >= self.bytes.len()
122 }
123
124 #[allow(clippy::should_implement_trait)] pub fn next(&mut self) -> Result<Option<Element>> {
147 if self.is_empty() {
148 return Ok(None);
149 }
150 let control = self.next_byte()?;
151 let elem_type = control & et::ELEMENT_TYPE_MASK;
152
153 if elem_type == et::END_OF_CONTAINER {
155 if control & tc::TAG_CONTROL_MASK != tc::ANONYMOUS {
156 return Err(Error::InvalidTagControl(control & tc::TAG_CONTROL_MASK));
157 }
158 if self.depth == 0 {
159 return Err(Error::UnexpectedEndOfContainer);
160 }
161 self.depth -= 1;
162 return Ok(Some(Element::ContainerEnd));
163 }
164
165 let tag = self.read_tag(control)?;
166
167 let kind = match elem_type {
169 et::STRUCTURE => Some(ContainerKind::Structure),
170 et::ARRAY => Some(ContainerKind::Array),
171 et::LIST => Some(ContainerKind::List),
172 _ => None,
173 };
174 if let Some(kind) = kind {
175 if self.depth >= MAX_DEPTH {
176 return Err(Error::ContainerTooDeep);
177 }
178 self.depth += 1;
179 return Ok(Some(Element::ContainerStart { tag, kind }));
180 }
181
182 let value = self.read_value_body(elem_type)?;
183 Ok(Some(Element::Scalar { tag, value }))
184 }
185
186 pub fn skip_container(&mut self) -> Result<()> {
230 let mut depth = 1usize;
231 while depth > 0 {
232 match self.next()? {
233 Some(Element::ContainerStart { .. }) => depth += 1,
234 Some(Element::ContainerEnd) => depth -= 1,
235 Some(Element::Scalar { .. }) => {}
236 None => return Err(Error::UnclosedContainer),
237 }
238 }
239 Ok(())
240 }
241
242 pub fn read_value(&mut self) -> Result<(Tag, Value)> {
259 let remaining_input = self.bytes.len().saturating_sub(self.pos);
277 if remaining_input <= self.element_budget {
278 self.read_value_inner::<false>()
279 } else {
280 self.read_value_inner::<true>()
281 }
282 }
283
284 fn read_value_inner<const CHARGE: bool>(&mut self) -> Result<(Tag, Value)> {
289 match self.next()? {
290 Some(Element::Scalar { tag, value }) => {
291 if CHARGE {
292 self.charge_element()?;
293 }
294 Ok((tag, value))
295 }
296 Some(Element::ContainerStart { tag, kind }) => {
297 if CHARGE {
298 self.charge_element()?;
299 }
300 let value = self.read_container_body::<CHARGE>(kind)?;
301 Ok((tag, value))
302 }
303 Some(Element::ContainerEnd) => Err(Error::UnexpectedEndOfContainer),
304 None => Err(Error::UnexpectedEof),
305 }
306 }
307
308 fn charge_element(&mut self) -> Result<()> {
314 self.element_budget = self
315 .element_budget
316 .checked_sub(1)
317 .ok_or(Error::ElementBudgetExceeded)?;
318 Ok(())
319 }
320
321 fn read_container_body<const CHARGE: bool>(&mut self, kind: ContainerKind) -> Result<Value> {
349 match kind {
354 ContainerKind::Array => {
355 let mut elements: Vec<Value> = Vec::new();
356 let mut budget = self.element_budget;
357 loop {
358 match self.next()? {
359 None => return Err(Error::UnclosedContainer),
360 Some(Element::ContainerEnd) => break,
361 Some(Element::Scalar { tag, value }) => {
362 if tag != Tag::Anonymous {
365 return Err(Error::NonAnonymousArrayTag);
366 }
367 if CHARGE {
368 budget =
369 budget.checked_sub(1).ok_or(Error::ElementBudgetExceeded)?;
370 }
371 elements.push(value);
372 }
373 Some(Element::ContainerStart {
374 tag,
375 kind: inner_kind,
376 }) => {
377 if tag != Tag::Anonymous {
378 return Err(Error::NonAnonymousArrayTag);
379 }
380 if CHARGE {
381 budget =
382 budget.checked_sub(1).ok_or(Error::ElementBudgetExceeded)?;
383 self.element_budget = budget;
384 }
385 elements.push(self.read_container_body::<CHARGE>(inner_kind)?);
386 if CHARGE {
387 budget = self.element_budget;
388 }
389 }
390 }
391 }
392 if CHARGE {
393 self.element_budget = budget;
394 }
395 Ok(Value::Array(elements))
396 }
397 ContainerKind::Structure | ContainerKind::List => {
398 let mut members: Vec<(Tag, Value)> = Vec::new();
399 let mut budget = self.element_budget;
400 loop {
401 match self.next()? {
402 None => return Err(Error::UnclosedContainer),
403 Some(Element::ContainerEnd) => break,
404 Some(Element::Scalar { tag, value }) => {
405 if CHARGE {
406 budget =
407 budget.checked_sub(1).ok_or(Error::ElementBudgetExceeded)?;
408 }
409 members.push((tag, value));
410 }
411 Some(Element::ContainerStart {
412 tag,
413 kind: inner_kind,
414 }) => {
415 if CHARGE {
416 budget =
417 budget.checked_sub(1).ok_or(Error::ElementBudgetExceeded)?;
418 self.element_budget = budget;
419 }
420 let inner = self.read_container_body::<CHARGE>(inner_kind)?;
421 members.push((tag, inner));
422 if CHARGE {
423 budget = self.element_budget;
424 }
425 }
426 }
427 }
428 if CHARGE {
429 self.element_budget = budget;
430 }
431 Ok(match kind {
432 ContainerKind::List => Value::List(members),
433 _ => Value::Structure(members),
435 })
436 }
437 }
438 }
439
440 fn next_byte(&mut self) -> Result<u8> {
441 let b = *self.bytes.get(self.pos).ok_or(Error::UnexpectedEof)?;
442 self.pos += 1;
443 Ok(b)
444 }
445
446 fn next_bytes(&mut self, n: usize) -> Result<&'a [u8]> {
447 let end = self.pos.checked_add(n).ok_or(Error::LengthOverflow)?;
448 let slice = self.bytes.get(self.pos..end).ok_or(Error::UnexpectedEof)?;
449 self.pos = end;
450 Ok(slice)
451 }
452
453 fn read_tag(&mut self, control: u8) -> Result<Tag> {
454 match control & tc::TAG_CONTROL_MASK {
455 tc::ANONYMOUS => Ok(Tag::Anonymous),
456 tc::CONTEXT => {
457 let n = self.next_byte()?;
458 Ok(Tag::Context(n))
459 }
460 tc::COMMON_PROFILE_2 => {
461 let raw: [u8; 2] = self
462 .next_bytes(2)?
463 .try_into()
464 .map_err(|_| Error::InternalSliceConversion)?;
465 Ok(Tag::CommonProfile(u32::from(u16::from_le_bytes(raw))))
466 }
467 tc::COMMON_PROFILE_4 => {
468 let raw: [u8; 4] = self
469 .next_bytes(4)?
470 .try_into()
471 .map_err(|_| Error::InternalSliceConversion)?;
472 Ok(Tag::CommonProfile(u32::from_le_bytes(raw)))
473 }
474 tc::IMPLICIT_PROFILE_2 => {
475 let raw: [u8; 2] = self
476 .next_bytes(2)?
477 .try_into()
478 .map_err(|_| Error::InternalSliceConversion)?;
479 Ok(Tag::ImplicitProfile(u32::from(u16::from_le_bytes(raw))))
480 }
481 tc::IMPLICIT_PROFILE_4 => {
482 let raw: [u8; 4] = self
483 .next_bytes(4)?
484 .try_into()
485 .map_err(|_| Error::InternalSliceConversion)?;
486 Ok(Tag::ImplicitProfile(u32::from_le_bytes(raw)))
487 }
488 tc::FULLY_QUALIFIED_6 => {
489 let vendor = self.read_u16_le()?;
490 let profile = self.read_u16_le()?;
491 let tag = u32::from(self.read_u16_le()?);
492 Ok(Tag::FullyQualified {
493 vendor,
494 profile,
495 tag,
496 })
497 }
498 tc::FULLY_QUALIFIED_8 => {
499 let vendor = self.read_u16_le()?;
500 let profile = self.read_u16_le()?;
501 let tag = self.read_u32_le()?;
502 Ok(Tag::FullyQualified {
503 vendor,
504 profile,
505 tag,
506 })
507 }
508 other => Err(Error::InvalidTagControl(other)),
512 }
513 }
514
515 fn read_u16_le(&mut self) -> Result<u16> {
516 let raw: [u8; 2] = self
517 .next_bytes(2)?
518 .try_into()
519 .map_err(|_| Error::InternalSliceConversion)?;
520 Ok(u16::from_le_bytes(raw))
521 }
522
523 fn read_u32_le(&mut self) -> Result<u32> {
524 let raw: [u8; 4] = self
525 .next_bytes(4)?
526 .try_into()
527 .map_err(|_| Error::InternalSliceConversion)?;
528 Ok(u32::from_le_bytes(raw))
529 }
530
531 #[allow(clippy::cast_possible_wrap)] fn read_value_body(&mut self, elem_type: u8) -> Result<Value> {
533 match elem_type {
534 et::BOOL_FALSE => Ok(Value::Bool(false)),
535 et::BOOL_TRUE => Ok(Value::Bool(true)),
536 et::NULL => Ok(Value::Null),
537 et::UINT8 => Ok(Value::Uint(u64::from(self.next_byte()?))),
538 et::UINT16 => {
539 let raw: [u8; 2] = self
540 .next_bytes(2)?
541 .try_into()
542 .map_err(|_| Error::InternalSliceConversion)?;
543 Ok(Value::Uint(u64::from(u16::from_le_bytes(raw))))
544 }
545 et::UINT32 => {
546 let raw: [u8; 4] = self
547 .next_bytes(4)?
548 .try_into()
549 .map_err(|_| Error::InternalSliceConversion)?;
550 Ok(Value::Uint(u64::from(u32::from_le_bytes(raw))))
551 }
552 et::UINT64 => {
553 let raw: [u8; 8] = self
554 .next_bytes(8)?
555 .try_into()
556 .map_err(|_| Error::InternalSliceConversion)?;
557 Ok(Value::Uint(u64::from_le_bytes(raw)))
558 }
559 et::INT8 => {
560 let b = self.next_byte()?;
561 Ok(Value::Int(i64::from(b as i8)))
562 }
563 et::INT16 => {
564 let raw: [u8; 2] = self
565 .next_bytes(2)?
566 .try_into()
567 .map_err(|_| Error::InternalSliceConversion)?;
568 Ok(Value::Int(i64::from(i16::from_le_bytes(raw))))
569 }
570 et::INT32 => {
571 let raw: [u8; 4] = self
572 .next_bytes(4)?
573 .try_into()
574 .map_err(|_| Error::InternalSliceConversion)?;
575 Ok(Value::Int(i64::from(i32::from_le_bytes(raw))))
576 }
577 et::INT64 => {
578 let raw: [u8; 8] = self
579 .next_bytes(8)?
580 .try_into()
581 .map_err(|_| Error::InternalSliceConversion)?;
582 Ok(Value::Int(i64::from_le_bytes(raw)))
583 }
584 et::FLOAT32 => {
585 let raw: [u8; 4] = self
586 .next_bytes(4)?
587 .try_into()
588 .map_err(|_| Error::InternalSliceConversion)?;
589 Ok(Value::Float(f32::from_le_bytes(raw)))
590 }
591 et::FLOAT64 => {
592 let raw: [u8; 8] = self
593 .next_bytes(8)?
594 .try_into()
595 .map_err(|_| Error::InternalSliceConversion)?;
596 Ok(Value::Double(f64::from_le_bytes(raw)))
597 }
598 et::UTF8_LEN8 | et::UTF8_LEN16 | et::UTF8_LEN32 | et::UTF8_LEN64 => {
599 let len = self.read_payload_len(elem_type)?;
600 self.read_utf8(len)
601 }
602 et::BYTES_LEN8 | et::BYTES_LEN16 | et::BYTES_LEN32 | et::BYTES_LEN64 => {
603 let len = self.read_payload_len(elem_type)?;
604 self.read_bytes(len)
605 }
606 other => Err(Error::InvalidElementType(other)),
607 }
608 }
609
610 fn read_payload_len(&mut self, elem_type: u8) -> Result<usize> {
614 match elem_type & 0b11 {
615 0b00 => Ok(usize::from(self.next_byte()?)),
616 0b01 => Ok(usize::from(self.read_u16_le()?)),
617 0b10 => usize::try_from(self.read_u32_le()?).map_err(|_| Error::LengthOverflow),
618 _ => usize::try_from(self.read_u64_le()?).map_err(|_| Error::LengthOverflow),
619 }
620 }
621
622 fn read_u64_le(&mut self) -> Result<u64> {
623 let raw: [u8; 8] = self
624 .next_bytes(8)?
625 .try_into()
626 .map_err(|_| Error::InternalSliceConversion)?;
627 Ok(u64::from_le_bytes(raw))
628 }
629
630 fn read_utf8(&mut self, len: usize) -> Result<Value> {
631 let bytes = self.next_bytes(len)?;
632 let s = core::str::from_utf8(bytes)?;
633 Ok(Value::Utf8(String::from(s)))
634 }
635
636 fn read_bytes(&mut self, len: usize) -> Result<Value> {
637 let bytes = self.next_bytes(len)?;
638 Ok(Value::Bytes(bytes.to_vec()))
639 }
640}
641
642#[cfg(test)]
643#[allow(clippy::unwrap_used)] mod tests {
645 use super::*;
646
647 #[test]
648 fn next_returns_none_on_empty_input() {
649 let mut r = TlvReader::new(&[]);
650 assert!(r.is_empty());
651 assert_eq!(r.next().unwrap(), None);
652 }
653
654 #[test]
655 fn next_decodes_bool_true_anonymous_vector_0001() {
656 let mut r = TlvReader::new(&[0x09]);
657 let el = r.next().unwrap().unwrap();
658 assert_eq!(
659 el,
660 Element::Scalar {
661 tag: Tag::Anonymous,
662 value: Value::Bool(true)
663 }
664 );
665 assert!(r.is_empty());
666 }
667
668 #[test]
669 fn next_decodes_bool_false() {
670 let mut r = TlvReader::new(&[0x08]);
671 let el = r.next().unwrap().unwrap();
672 assert_eq!(
673 el,
674 Element::Scalar {
675 tag: Tag::Anonymous,
676 value: Value::Bool(false)
677 }
678 );
679 }
680
681 #[test]
682 fn next_decodes_null_vector_implied() {
683 let mut r = TlvReader::new(&[0x14]);
684 let el = r.next().unwrap().unwrap();
685 assert_eq!(
686 el,
687 Element::Scalar {
688 tag: Tag::Anonymous,
689 value: Value::Null
690 }
691 );
692 }
693
694 #[test]
695 fn next_decodes_uint8_42_vector_0003() {
696 let mut r = TlvReader::new(&[0x04, 0x2A]);
697 let el = r.next().unwrap().unwrap();
698 assert_eq!(
699 el,
700 Element::Scalar {
701 tag: Tag::Anonymous,
702 value: Value::Uint(42)
703 }
704 );
705 }
706
707 #[test]
708 fn next_decodes_uint16_0x1234() {
709 let mut r = TlvReader::new(&[0x05, 0x34, 0x12]);
710 let el = r.next().unwrap().unwrap();
711 assert_eq!(
712 el,
713 Element::Scalar {
714 tag: Tag::Anonymous,
715 value: Value::Uint(0x1234)
716 }
717 );
718 }
719
720 #[test]
721 fn next_decodes_uint32_0xcafebabe() {
722 let mut r = TlvReader::new(&[0x06, 0xBE, 0xBA, 0xFE, 0xCA]);
723 let el = r.next().unwrap().unwrap();
724 assert_eq!(
725 el,
726 Element::Scalar {
727 tag: Tag::Anonymous,
728 value: Value::Uint(0xCAFE_BABE)
729 }
730 );
731 }
732
733 #[test]
734 fn next_decodes_uint64_big() {
735 let bytes = [0x07, 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01];
736 let mut r = TlvReader::new(&bytes);
737 let el = r.next().unwrap().unwrap();
738 assert_eq!(
739 el,
740 Element::Scalar {
741 tag: Tag::Anonymous,
742 value: Value::Uint(0x0123_4567_89AB_CDEF),
743 }
744 );
745 }
746
747 #[test]
748 fn next_decodes_int8_neg17_vector_0008() {
749 let mut r = TlvReader::new(&[0x00, 0xEF]);
750 let el = r.next().unwrap().unwrap();
751 assert_eq!(
752 el,
753 Element::Scalar {
754 tag: Tag::Anonymous,
755 value: Value::Int(-17)
756 }
757 );
758 }
759
760 #[test]
761 fn next_decodes_int16_neg129() {
762 let mut r = TlvReader::new(&[0x01, 0x7F, 0xFF]);
763 let el = r.next().unwrap().unwrap();
764 assert_eq!(
765 el,
766 Element::Scalar {
767 tag: Tag::Anonymous,
768 value: Value::Int(-129)
769 }
770 );
771 }
772
773 #[test]
774 fn next_decodes_int32_min() {
775 let mut r = TlvReader::new(&[0x02, 0x00, 0x00, 0x00, 0x80]);
776 let el = r.next().unwrap().unwrap();
777 assert_eq!(
778 el,
779 Element::Scalar {
780 tag: Tag::Anonymous,
781 value: Value::Int(i64::from(i32::MIN))
782 }
783 );
784 }
785
786 #[test]
787 fn next_decodes_int64_min() {
788 let bytes = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80];
789 let mut r = TlvReader::new(&bytes);
790 let el = r.next().unwrap().unwrap();
791 assert_eq!(
792 el,
793 Element::Scalar {
794 tag: Tag::Anonymous,
795 value: Value::Int(i64::MIN)
796 }
797 );
798 }
799
800 #[test]
801 fn next_decodes_float32_zero_vector_0013() {
802 let mut r = TlvReader::new(&[0x0A, 0x00, 0x00, 0x00, 0x00]);
803 let el = r.next().unwrap().unwrap();
804 assert_eq!(
805 el,
806 Element::Scalar {
807 tag: Tag::Anonymous,
808 value: Value::Float(0.0)
809 }
810 );
811 }
812
813 #[test]
814 fn next_decodes_float64_zero_vector_0014() {
815 let bytes = [0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
816 let mut r = TlvReader::new(&bytes);
817 let el = r.next().unwrap().unwrap();
818 assert_eq!(
819 el,
820 Element::Scalar {
821 tag: Tag::Anonymous,
822 value: Value::Double(0.0)
823 }
824 );
825 }
826
827 #[test]
828 fn next_decodes_uint_with_context_tag_5() {
829 let mut r = TlvReader::new(&[0x24, 0x05, 0x2A]);
830 let el = r.next().unwrap().unwrap();
831 assert_eq!(
832 el,
833 Element::Scalar {
834 tag: Tag::Context(5),
835 value: Value::Uint(42)
836 }
837 );
838 }
839
840 #[test]
841 fn next_errors_on_unexpected_eof_in_payload() {
842 let mut r = TlvReader::new(&[0x05]); assert!(matches!(r.next(), Err(Error::UnexpectedEof)));
844 }
845
846 #[test]
847 fn next_decodes_uint_with_common_profile_2_byte_tag() {
848 let mut r = TlvReader::new(&[0x44, 0x07, 0x00, 0x2A]);
849 let el = r.next().unwrap().unwrap();
850 assert_eq!(
851 el,
852 Element::Scalar {
853 tag: Tag::CommonProfile(7),
854 value: Value::Uint(42)
855 }
856 );
857 }
858
859 #[test]
860 fn next_decodes_uint_with_common_profile_4_byte_tag() {
861 let mut r = TlvReader::new(&[0x64, 0x45, 0x23, 0x01, 0x00, 0x2A]);
862 let el = r.next().unwrap().unwrap();
863 assert_eq!(
864 el,
865 Element::Scalar {
866 tag: Tag::CommonProfile(0x0001_2345),
867 value: Value::Uint(42)
868 }
869 );
870 }
871
872 #[test]
873 fn next_decodes_uint_with_implicit_profile_2_byte_tag() {
874 let mut r = TlvReader::new(&[0x84, 0x07, 0x00, 0x2A]);
875 let el = r.next().unwrap().unwrap();
876 assert_eq!(
877 el,
878 Element::Scalar {
879 tag: Tag::ImplicitProfile(7),
880 value: Value::Uint(42)
881 }
882 );
883 }
884
885 #[test]
886 fn next_decodes_uint_with_implicit_profile_4_byte_tag() {
887 let mut r = TlvReader::new(&[0xA4, 0x45, 0x23, 0x01, 0x00, 0x2A]);
888 let el = r.next().unwrap().unwrap();
889 assert_eq!(
890 el,
891 Element::Scalar {
892 tag: Tag::ImplicitProfile(0x0001_2345),
893 value: Value::Uint(42)
894 }
895 );
896 }
897
898 #[test]
899 fn next_decodes_uint_with_fully_qualified_6_byte() {
900 let mut r = TlvReader::new(&[0xC4, 0xF1, 0xFF, 0x06, 0x00, 0x05, 0x00, 0x2A]);
901 let el = r.next().unwrap().unwrap();
902 assert_eq!(
903 el,
904 Element::Scalar {
905 tag: Tag::FullyQualified {
906 vendor: 0xFFF1,
907 profile: 0x0006,
908 tag: 5
909 },
910 value: Value::Uint(42),
911 }
912 );
913 }
914
915 #[test]
916 fn next_decodes_uint_with_fully_qualified_8_byte() {
917 let mut r = TlvReader::new(&[0xE4, 0xF1, 0xFF, 0x06, 0x00, 0x45, 0x23, 0x01, 0x00, 0x2A]);
918 let el = r.next().unwrap().unwrap();
919 assert_eq!(
920 el,
921 Element::Scalar {
922 tag: Tag::FullyQualified {
923 vendor: 0xFFF1,
924 profile: 0x0006,
925 tag: 0x0001_2345
926 },
927 value: Value::Uint(42),
928 }
929 );
930 }
931
932 #[test]
933 fn read_value_returns_tag_and_value_for_scalar() {
934 let mut r = TlvReader::new(&[0x24, 0x05, 0x2A]);
935 let (tag, value) = r.read_value().unwrap();
936 assert_eq!(tag, Tag::Context(5));
937 assert_eq!(value, Value::Uint(42));
938 }
939
940 #[test]
941 fn read_value_errors_on_empty_input() {
942 let mut r = TlvReader::new(&[]);
943 assert!(matches!(r.read_value(), Err(Error::UnexpectedEof)));
944 }
945
946 #[test]
947 fn next_decodes_utf8_hello_vector_0015() {
948 let bytes = [0x0C, 0x06, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21];
949 let mut r = TlvReader::new(&bytes);
950 let el = r.next().unwrap().unwrap();
951 assert_eq!(
952 el,
953 Element::Scalar {
954 tag: Tag::Anonymous,
955 value: Value::Utf8(String::from("Hello!")),
956 }
957 );
958 }
959
960 #[test]
961 fn next_decodes_utf8_empty_vector_0016() {
962 let bytes = [0x0C, 0x00];
963 let mut r = TlvReader::new(&bytes);
964 let el = r.next().unwrap().unwrap();
965 assert_eq!(
966 el,
967 Element::Scalar {
968 tag: Tag::Anonymous,
969 value: Value::Utf8(String::new()),
970 }
971 );
972 }
973
974 #[test]
975 fn next_decodes_utf8_len16_path() {
976 let mut bytes = vec![0x0D, 0x00, 0x01]; bytes.extend(std::iter::repeat_n(b'a', 256));
978 let mut r = TlvReader::new(&bytes);
979 let el = r.next().unwrap().unwrap();
980 let Element::Scalar {
981 value: Value::Utf8(s),
982 ..
983 } = el
984 else {
985 panic!("wrong variant")
986 };
987 assert_eq!(s.len(), 256);
988 assert!(s.bytes().all(|b| b == b'a'));
989 }
990
991 #[test]
992 fn next_decodes_bytes_five_bytes_vector_0017() {
993 let bytes = [0x10, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04];
994 let mut r = TlvReader::new(&bytes);
995 let el = r.next().unwrap().unwrap();
996 assert_eq!(
997 el,
998 Element::Scalar {
999 tag: Tag::Anonymous,
1000 value: Value::Bytes(vec![0x00, 0x01, 0x02, 0x03, 0x04]),
1001 }
1002 );
1003 }
1004
1005 #[test]
1006 fn next_decodes_bytes_empty_vector_0018() {
1007 let bytes = [0x10, 0x00];
1008 let mut r = TlvReader::new(&bytes);
1009 let el = r.next().unwrap().unwrap();
1010 assert_eq!(
1011 el,
1012 Element::Scalar {
1013 tag: Tag::Anonymous,
1014 value: Value::Bytes(Vec::new()),
1015 }
1016 );
1017 }
1018
1019 #[test]
1020 fn next_errors_on_invalid_utf8() {
1021 let bytes = [0x0C, 0x01, 0xFF];
1022 let mut r = TlvReader::new(&bytes);
1023 assert!(matches!(r.next(), Err(Error::InvalidUtf8(_))));
1024 }
1025
1026 #[test]
1027 fn next_errors_on_truncated_utf8_payload() {
1028 let bytes = [0x0C, 0x05, b'H', b'i']; let mut r = TlvReader::new(&bytes);
1030 assert!(matches!(r.next(), Err(Error::UnexpectedEof)));
1031 }
1032
1033 #[test]
1036 fn next_decodes_structure_start_and_end_vector_0019() {
1037 let mut r = TlvReader::new(&[0x15, 0x18]);
1038 let el = r.next().unwrap().unwrap();
1039 assert_eq!(
1040 el,
1041 Element::ContainerStart {
1042 tag: Tag::Anonymous,
1043 kind: ContainerKind::Structure,
1044 }
1045 );
1046 let el = r.next().unwrap().unwrap();
1047 assert_eq!(el, Element::ContainerEnd);
1048 assert!(r.next().unwrap().is_none());
1049 }
1050
1051 #[test]
1052 fn next_decodes_array_start_and_end_vector_0020() {
1053 let mut r = TlvReader::new(&[0x16, 0x18]);
1054 assert_eq!(
1055 r.next().unwrap().unwrap(),
1056 Element::ContainerStart {
1057 tag: Tag::Anonymous,
1058 kind: ContainerKind::Array,
1059 }
1060 );
1061 assert_eq!(r.next().unwrap().unwrap(), Element::ContainerEnd);
1062 }
1063
1064 #[test]
1065 fn next_decodes_list_start_and_end() {
1066 let mut r = TlvReader::new(&[0x17, 0x18]);
1067 assert_eq!(
1068 r.next().unwrap().unwrap(),
1069 Element::ContainerStart {
1070 tag: Tag::Anonymous,
1071 kind: ContainerKind::List,
1072 }
1073 );
1074 assert_eq!(r.next().unwrap().unwrap(), Element::ContainerEnd);
1075 }
1076
1077 #[test]
1078 fn next_decodes_structure_with_child_streaming() {
1079 let mut r = TlvReader::new(&[0x15, 0x24, 0x00, 0x2A, 0x18]);
1080 assert_eq!(
1081 r.next().unwrap().unwrap(),
1082 Element::ContainerStart {
1083 tag: Tag::Anonymous,
1084 kind: ContainerKind::Structure,
1085 }
1086 );
1087 assert_eq!(
1088 r.next().unwrap().unwrap(),
1089 Element::Scalar {
1090 tag: Tag::Context(0),
1091 value: Value::Uint(42),
1092 }
1093 );
1094 assert_eq!(r.next().unwrap().unwrap(), Element::ContainerEnd);
1095 assert!(r.next().unwrap().is_none());
1096 }
1097
1098 #[test]
1099 fn next_errors_on_end_of_container_at_top_level() {
1100 let mut r = TlvReader::new(&[0x18]);
1101 assert!(matches!(r.next(), Err(Error::UnexpectedEndOfContainer)));
1102 }
1103
1104 #[test]
1105 fn next_errors_on_end_of_container_with_non_anonymous_tag_form() {
1106 let mut r = TlvReader::new(&[0x38, 0x05]);
1108 assert!(matches!(r.next(), Err(Error::InvalidTagControl(_))));
1109 }
1110
1111 #[test]
1112 fn next_errors_on_excessive_nesting() {
1113 let bytes: Vec<u8> = std::iter::repeat_n(0x15u8, 33).collect();
1114 let mut r = TlvReader::new(&bytes);
1115 for _ in 0..32 {
1116 assert!(matches!(
1117 r.next().unwrap().unwrap(),
1118 Element::ContainerStart {
1119 kind: ContainerKind::Structure,
1120 ..
1121 },
1122 ));
1123 }
1124 assert!(matches!(r.next(), Err(Error::ContainerTooDeep)));
1125 }
1126
1127 #[test]
1128 fn depth_returns_to_zero_after_balanced_close() {
1129 {
1132 let mut r = TlvReader::new(&[0x15, 0x18]);
1133 let _ = r.next(); let _ = r.next(); }
1136 let mut r2 = TlvReader::new(&[0x18]);
1137 assert!(matches!(r2.next(), Err(Error::UnexpectedEndOfContainer)));
1138 }
1139
1140 #[test]
1143 fn read_value_returns_empty_structure_vector_0019() {
1144 let mut r = TlvReader::new(&[0x15, 0x18]);
1145 let (tag, value) = r.read_value().unwrap();
1146 assert_eq!(tag, Tag::Anonymous);
1147 assert_eq!(value, Value::Structure(Vec::new()));
1148 }
1149
1150 #[test]
1151 fn read_value_returns_empty_array_vector_0020() {
1152 let mut r = TlvReader::new(&[0x16, 0x18]);
1153 let (tag, value) = r.read_value().unwrap();
1154 assert_eq!(tag, Tag::Anonymous);
1155 assert_eq!(value, Value::Array(Vec::new()));
1156 }
1157
1158 #[test]
1159 fn read_value_returns_structure_with_ctx_member_vector_0021() {
1160 let mut r = TlvReader::new(&[0x15, 0x24, 0x00, 0x2A, 0x18]);
1161 let (tag, value) = r.read_value().unwrap();
1162 assert_eq!(tag, Tag::Anonymous);
1163 assert_eq!(
1164 value,
1165 Value::Structure(vec![(Tag::Context(0), Value::Uint(42))])
1166 );
1167 }
1168
1169 #[test]
1170 fn read_value_returns_array_of_three_uint8_vector_0022() {
1171 let mut r = TlvReader::new(&[0x16, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x18]);
1172 let (tag, value) = r.read_value().unwrap();
1173 assert_eq!(tag, Tag::Anonymous);
1174 assert_eq!(
1175 value,
1176 Value::Array(vec![Value::Uint(1), Value::Uint(2), Value::Uint(3)])
1177 );
1178 }
1179
1180 #[test]
1181 fn read_value_returns_structure_with_bool_at_ctx7_vector_0023() {
1182 let mut r = TlvReader::new(&[0x15, 0x29, 0x07, 0x18]);
1183 let (tag, value) = r.read_value().unwrap();
1184 assert_eq!(tag, Tag::Anonymous);
1185 assert_eq!(
1186 value,
1187 Value::Structure(vec![(Tag::Context(7), Value::Bool(true))])
1188 );
1189 }
1190
1191 #[test]
1192 fn read_value_returns_empty_list() {
1193 let mut r = TlvReader::new(&[0x17, 0x18]);
1194 let (tag, value) = r.read_value().unwrap();
1195 assert_eq!(tag, Tag::Anonymous);
1196 assert_eq!(value, Value::List(Vec::new()));
1197 }
1198
1199 #[test]
1200 fn read_value_handles_nested_structure() {
1201 let mut r = TlvReader::new(&[0x15, 0x35, 0x00, 0x24, 0x00, 0x2A, 0x18, 0x18]);
1202 let (tag, value) = r.read_value().unwrap();
1203 assert_eq!(tag, Tag::Anonymous);
1204 let inner = Value::Structure(vec![(Tag::Context(0), Value::Uint(42))]);
1205 let outer = Value::Structure(vec![(Tag::Context(0), inner)]);
1206 assert_eq!(value, outer);
1207 }
1208
1209 #[test]
1210 fn read_value_errors_on_unclosed_container() {
1211 let mut r = TlvReader::new(&[0x15]);
1212 assert!(matches!(r.read_value(), Err(Error::UnclosedContainer)));
1213 }
1214
1215 #[test]
1216 fn read_value_errors_on_dangling_end_of_container() {
1217 let mut r = TlvReader::new(&[0x18]);
1218 assert!(matches!(
1219 r.read_value(),
1220 Err(Error::UnexpectedEndOfContainer)
1221 ));
1222 }
1223
1224 #[test]
1227 fn read_value_rejects_array_with_context_tagged_child() {
1228 let mut r = TlvReader::new(&[0x16, 0x24, 0x00, 0x2A, 0x18]);
1232 assert!(matches!(r.read_value(), Err(Error::NonAnonymousArrayTag)));
1233 }
1234
1235 #[test]
1236 fn read_value_rejects_array_with_context_tagged_container_child() {
1237 let mut r = TlvReader::new(&[0x16, 0x35, 0x00, 0x18, 0x18]);
1240 assert!(matches!(r.read_value(), Err(Error::NonAnonymousArrayTag)));
1241 }
1242
1243 #[test]
1244 fn read_value_accepts_array_with_anonymous_children() {
1245 let mut r = TlvReader::new(&[0x16, 0x04, 0x01, 0x04, 0x02, 0x18]);
1248 let (tag, value) = r.read_value().unwrap();
1249 assert_eq!(tag, Tag::Anonymous);
1250 assert_eq!(value, Value::Array(vec![Value::Uint(1), Value::Uint(2)]));
1251 }
1252
1253 #[test]
1254 fn read_value_errors_when_element_budget_is_exceeded() {
1255 let bytes = [0x16, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x18];
1261 let mut r = TlvReader::with_element_budget(&bytes, 3);
1262 assert!(matches!(r.read_value(), Err(Error::ElementBudgetExceeded)));
1263 }
1264
1265 #[test]
1266 fn read_value_fast_path_at_budget_equal_to_input_len() {
1267 let bytes = [0x16, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x18];
1271 let mut r = TlvReader::with_element_budget(&bytes, bytes.len());
1272 let (_, value) = r.read_value().unwrap();
1273 assert_eq!(
1274 value,
1275 Value::Array(vec![Value::Uint(1), Value::Uint(2), Value::Uint(3)])
1276 );
1277 }
1278
1279 #[test]
1280 fn read_value_charged_path_at_budget_one_below_input_len() {
1281 let bytes = [0x16, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x18];
1284 let mut r = TlvReader::with_element_budget(&bytes, 7);
1285 let (_, value) = r.read_value().unwrap();
1286 assert_eq!(
1287 value,
1288 Value::Array(vec![Value::Uint(1), Value::Uint(2), Value::Uint(3)])
1289 );
1290 }
1291
1292 #[test]
1293 fn read_value_succeeds_at_exactly_the_element_budget() {
1294 let bytes = [0x16, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x18];
1296 let mut r = TlvReader::with_element_budget(&bytes, 4);
1297 let (_, value) = r.read_value().unwrap();
1298 assert_eq!(
1299 value,
1300 Value::Array(vec![Value::Uint(1), Value::Uint(2), Value::Uint(3)])
1301 );
1302 }
1303
1304 #[test]
1305 fn read_value_budget_counts_a_single_scalar() {
1306 let mut r = TlvReader::with_element_budget(&[0x04, 0x2A], 0);
1308 assert!(matches!(r.read_value(), Err(Error::ElementBudgetExceeded)));
1309 let mut r = TlvReader::with_element_budget(&[0x04, 0x2A], 1);
1310 assert_eq!(r.read_value().unwrap(), (Tag::Anonymous, Value::Uint(42)));
1311 }
1312
1313 #[test]
1314 fn fixed_width_int_decode_still_works() {
1315 let mut r = TlvReader::new(&[0x05, 0x34, 0x12]);
1320 assert_eq!(
1321 r.next().unwrap().unwrap(),
1322 Element::Scalar {
1323 tag: Tag::Anonymous,
1324 value: Value::Uint(0x1234),
1325 }
1326 );
1327 }
1328
1329 fn struct_with_nested() -> Vec<u8> {
1334 let mut buf = Vec::new();
1335 let mut w = crate::writer::TlvWriter::new(&mut buf);
1336 w.start_structure(Tag::Anonymous).unwrap();
1337 w.put_uint(Tag::Context(0), 7).unwrap();
1338 w.start_structure(Tag::Context(9)).unwrap();
1339 w.put_uint(Tag::Context(0), 1).unwrap();
1340 w.end_container().unwrap();
1341 w.put_uint(Tag::Context(1), 42).unwrap();
1342 w.end_container().unwrap();
1343 buf
1344 }
1345
1346 #[test]
1347 fn skip_container_drains_nested_struct_and_positions_after() {
1348 let buf = struct_with_nested();
1349 let mut r = TlvReader::new(&buf);
1350 assert!(matches!(
1352 r.next().unwrap(),
1353 Some(Element::ContainerStart {
1354 kind: ContainerKind::Structure,
1355 ..
1356 })
1357 ));
1358 assert!(matches!(r.next().unwrap(), Some(Element::Scalar { .. })));
1360 assert!(matches!(
1362 r.next().unwrap(),
1363 Some(Element::ContainerStart {
1364 kind: ContainerKind::Structure,
1365 ..
1366 })
1367 ));
1368 r.skip_container().unwrap();
1369 match r.next().unwrap() {
1371 Some(Element::Scalar {
1372 tag: Tag::Context(1),
1373 value: Value::Uint(v),
1374 }) => {
1375 assert_eq!(v, 42);
1376 }
1377 other => panic!("expected ctx1=42 after skip, got {other:?}"),
1378 }
1379 assert!(matches!(r.next().unwrap(), Some(Element::ContainerEnd)));
1381 assert!(r.next().unwrap().is_none());
1382 }
1383
1384 #[test]
1385 fn skip_container_handles_array_and_list_and_empty() {
1386 for kind_byte in ["array", "list", "empty"] {
1387 let mut buf = Vec::new();
1388 let mut w = crate::writer::TlvWriter::new(&mut buf);
1389 w.start_structure(Tag::Anonymous).unwrap();
1390 match kind_byte {
1391 "array" => {
1392 w.start_array(Tag::Context(0)).unwrap();
1393 w.put_uint(Tag::Anonymous, 1).unwrap();
1394 w.put_uint(Tag::Anonymous, 2).unwrap();
1395 w.end_container().unwrap();
1396 }
1397 "list" => {
1398 w.start_list(Tag::Context(0)).unwrap();
1399 w.put_uint(Tag::Context(5), 9).unwrap();
1400 w.end_container().unwrap();
1401 }
1402 _ => {
1403 w.start_structure(Tag::Context(0)).unwrap();
1404 w.end_container().unwrap();
1405 }
1406 }
1407 w.put_uint(Tag::Context(1), 99).unwrap();
1408 w.end_container().unwrap();
1409
1410 let mut r = TlvReader::new(&buf);
1411 assert!(matches!(
1412 r.next().unwrap(),
1413 Some(Element::ContainerStart { .. })
1414 ));
1415 assert!(matches!(
1416 r.next().unwrap(),
1417 Some(Element::ContainerStart { .. })
1418 ));
1419 r.skip_container().unwrap();
1420 match r.next().unwrap() {
1421 Some(Element::Scalar {
1422 tag: Tag::Context(1),
1423 value: Value::Uint(v),
1424 }) => {
1425 assert_eq!(v, 99, "kind {kind_byte}");
1426 }
1427 other => panic!("kind {kind_byte}: expected ctx1=99, got {other:?}"),
1428 }
1429 }
1430 }
1431
1432 #[test]
1433 fn skip_container_unclosed_is_error() {
1434 let mut buf = Vec::new();
1436 {
1437 let mut w = crate::writer::TlvWriter::new(&mut buf);
1438 w.start_structure(Tag::Anonymous).unwrap();
1439 w.start_structure(Tag::Context(0)).unwrap();
1440 w.put_uint(Tag::Anonymous, 1).unwrap();
1441 }
1443 let mut r = TlvReader::new(&buf);
1444 assert!(matches!(
1445 r.next().unwrap(),
1446 Some(Element::ContainerStart { .. })
1447 ));
1448 assert!(matches!(
1449 r.next().unwrap(),
1450 Some(Element::ContainerStart { .. })
1451 ));
1452 assert!(matches!(r.skip_container(), Err(Error::UnclosedContainer)));
1453 }
1454}