From ebf39617c62e65dae9472a7da6cc82557e9e3fe8 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:23:31 +0100 Subject: [PATCH] fix: derive(Sequence) on field: Option<&'a [u8]> (#1675) * fix: derive(Sequence) on field: Option<&'a [u8]> * undo TryFrom<&[u8]> * fix: add TryFrom<&&'a [u8]> for OctetStringRef * rm &&&'a [u8] Co-authored-by: Arthur Gautier * docs: TryFrom<&&'a [u8]> Co-authored-by: Arthur Gautier * OctetStringRef::new Co-authored-by: Arthur Gautier * fmt space --------- Co-authored-by: Arthur Gautier --- der/src/asn1/octet_string.rs | 9 +++++++++ der/tests/derive.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/der/src/asn1/octet_string.rs b/der/src/asn1/octet_string.rs index e0333b1a3..98861ed44 100644 --- a/der/src/asn1/octet_string.rs +++ b/der/src/asn1/octet_string.rs @@ -104,6 +104,15 @@ impl<'a> TryFrom<&'a [u8]> for OctetStringRef<'a> { } } +/// Hack for simplifying the custom derive use case. +impl<'a> TryFrom<&&'a [u8]> for OctetStringRef<'a> { + type Error = Error; + + fn try_from(byte_slice: &&'a [u8]) -> Result { + OctetStringRef::new(byte_slice) + } +} + #[cfg(feature = "alloc")] pub use self::allocating::OctetString; diff --git a/der/tests/derive.rs b/der/tests/derive.rs index 30062bf82..cad6c3697 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -404,7 +404,7 @@ mod sequence { const ALGORITHM_IDENTIFIER_DER: &[u8] = &hex!("30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07"); - #[derive(Sequence)] + #[derive(Sequence, Default, Eq, PartialEq, Debug)] #[asn1(tag_mode = "IMPLICIT")] pub struct TypeCheckExpandedSequenceFieldAttributeCombinations<'a> { pub simple: bool, @@ -423,7 +423,34 @@ mod sequence { #[asn1(context_specific = "3", default = "default_false_example")] pub context_specific_default: bool, #[asn1(type = "BIT STRING", context_specific = "4", optional = "true")] - pub typed_context_specific_optional: Option<&'a [u8]>, + pub typed_context_specific_optional_bits: Option<&'a [u8]>, + #[asn1(type = "OCTET STRING", context_specific = "5", optional = "true")] + pub typed_context_specific_optional_implicit: Option<&'a [u8]>, + #[asn1( + type = "OCTET STRING", + context_specific = "6", + optional = "true", + tag_mode = "EXPLICIT" + )] + pub typed_context_specific_optional_explicit: Option<&'a [u8]>, + } + + #[test] + fn type_combinations_instance() { + let obj = TypeCheckExpandedSequenceFieldAttributeCombinations { + context_specific_optional: Some(true), + typed_context_specific: &[0, 1], + typed_context_specific_optional_bits: Some(&[2, 3]), + typed_context_specific_optional_implicit: Some(&[4, 5, 6]), + typed_context_specific_optional_explicit: Some(&[7, 8]), + + ..Default::default() + }; + + let der_encoded = obj.to_der().unwrap(); + let obj_decoded = + TypeCheckExpandedSequenceFieldAttributeCombinations::from_der(&der_encoded).unwrap(); + assert_eq!(obj, obj_decoded); } #[derive(Sequence)]