Coverage Report

Created: 2025-12-28 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/asn1-rs-0.7.0/src/debug.rs
Line
Count
Source
1
#![allow(unused_imports)]
2
3
use crate::ParseResult;
4
5
pub(crate) mod macros {
6
    macro_rules! debug_eprintln {
7
    ($msg: expr, $( $args:expr ),* ) => {
8
        #[cfg(feature = "debug")]
9
        {
10
            use colored::Colorize;
11
            let s = $msg.to_string().green();
12
            eprintln!("{} {}", s, format!($($args),*));
13
        }
14
    };
15
}
16
17
    #[allow(unused_macros)]
18
    macro_rules! trace_eprintln {
19
    ($msg: expr, $( $args:expr ),* ) => {
20
        #[cfg(feature = "trace")]
21
        {
22
            use colored::Colorize;
23
            let s = $msg.to_string().green();
24
            eprintln!("{} {}", s, format!($($args),*));
25
        }
26
    };
27
}
28
29
    pub(crate) use debug_eprintln;
30
    pub(crate) use trace_eprintln;
31
}
32
33
use macros::*;
34
35
#[cfg(feature = "debug")]
36
fn eprintln_hex_dump(bytes: &[u8], max_len: usize) {
37
    use core::cmp::min;
38
    use nom::HexDisplay;
39
40
    let m = min(bytes.len(), max_len);
41
    eprint!("{}", &bytes[..m].to_hex(16));
42
    if bytes.len() > max_len {
43
        eprintln!("... <continued>");
44
    }
45
}
46
47
#[cfg(not(feature = "debug"))]
48
#[inline]
49
0
pub fn trace_generic<F, I, O, E>(_msg: &str, _fname: &str, f: F, input: I) -> Result<O, E>
50
0
where
51
0
    F: Fn(I) -> Result<O, E>,
52
{
53
0
    f(input)
54
0
}
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<alloc::vec::Vec<asn1_rs::asn1_types::oid::Oid> as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], alloc::vec::Vec<asn1_rs::asn1_types::oid::Oid>), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<alloc::vec::Vec<x509_parser::extensions::policymappings::PolicyMapping> as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], alloc::vec::Vec<x509_parser::extensions::policymappings::PolicyMapping>), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<asn1_rs::asn1_types::generalizedtime::GeneralizedTime as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], asn1_rs::asn1_types::generalizedtime::GeneralizedTime), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<asn1_rs::asn1_types::oid::Oid as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], asn1_rs::asn1_types::oid::Oid), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<asn1_rs::asn1_types::integer::Integer as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], asn1_rs::asn1_types::integer::Integer), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<asn1_rs::asn1_types::utctime::UtcTime as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], asn1_rs::asn1_types::utctime::UtcTime), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<asn1_rs::asn1_types::bitstring::BitString as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], asn1_rs::asn1_types::bitstring::BitString), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<&[u8] as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], &[u8]), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u32 as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], u32), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u64 as asn1_rs::traits::FromDer>::from_der::{closure#0}, &[u8], (&[u8], u64), nom::internal::Err<asn1_rs::error::Error>>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u8 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, u8, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<i8 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, i8, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<i16 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, i16, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<i32 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, i32, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<i64 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, i64, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<i128 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, i128, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u16 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, u16, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u32 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, u32, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u64 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, u64, asn1_rs::error::Error>
Unexecuted instantiation: asn1_rs::debug::trace_generic::<<u128 as core::convert::TryFrom<&asn1_rs::asn1_types::any::Any>>::try_from::{closure#0}, &asn1_rs::asn1_types::any::Any, u128, asn1_rs::error::Error>
55
56
#[cfg(feature = "debug")]
57
pub fn trace_generic<F, I, O, E>(msg: &str, fname: &str, f: F, input: I) -> Result<O, E>
58
where
59
    F: Fn(I) -> Result<O, E>,
60
    E: core::fmt::Display,
61
{
62
    trace_eprintln!(msg, "⤷ {}", fname);
63
    let output = f(input);
64
    match &output {
65
        Err(e) => {
66
            debug_eprintln!(msg, "↯ {} failed: {}", fname, e.to_string().red());
67
        }
68
        _ => {
69
            debug_eprintln!(msg, "⤶ {}", fname);
70
        }
71
    }
72
    output
73
}
74
75
#[cfg(not(feature = "debug"))]
76
#[inline]
77
0
pub fn trace<'a, T, E, F>(_msg: &str, f: F, input: &'a [u8]) -> ParseResult<'a, T, E>
78
0
where
79
0
    F: Fn(&'a [u8]) -> ParseResult<'a, T, E>,
80
{
81
0
    f(input)
82
0
}
Unexecuted instantiation: asn1_rs::debug::trace::<asn1_rs::asn1_types::any::Any, asn1_rs::error::Error, asn1_rs::asn1_types::any::parse_ber_any>
Unexecuted instantiation: asn1_rs::debug::trace::<asn1_rs::asn1_types::any::Any, asn1_rs::error::Error, asn1_rs::asn1_types::any::parse_der_any>
83
84
#[cfg(feature = "debug")]
85
pub fn trace<'a, T, E, F>(msg: &str, f: F, input: &'a [u8]) -> ParseResult<'a, T, E>
86
where
87
    F: Fn(&'a [u8]) -> ParseResult<'a, T, E>,
88
{
89
    trace_eprintln!(
90
        msg,
91
        "⤷ input (len={}, type={})",
92
        input.len(),
93
        core::any::type_name::<T>()
94
    );
95
    let res = f(input);
96
    match &res {
97
        Ok((_rem, _)) => {
98
            trace_eprintln!(
99
                msg,
100
                "⤶ Parsed {} bytes, {} remaining",
101
                input.len() - _rem.len(),
102
                _rem.len()
103
            );
104
        }
105
        Err(_) => {
106
            // NOTE: we do not need to print error, caller should print it
107
            debug_eprintln!(msg, "↯ Parsing failed at location:");
108
            eprintln_hex_dump(input, 16);
109
        }
110
    }
111
    res
112
}
113
114
#[cfg(feature = "debug")]
115
#[cfg(test)]
116
mod tests {
117
118
    use std::collections::HashSet;
119
120
    use crate::*;
121
    use alloc::collections::BTreeSet;
122
    use hex_literal::hex;
123
124
    #[test]
125
    fn debug_from_ber_any() {
126
        assert!(Any::from_ber(&hex!("01 01 ff")).is_ok());
127
    }
128
129
    #[test]
130
    fn debug_from_ber_failures() {
131
        // wrong type
132
        eprintln!("--");
133
        assert!(<Vec<u16>>::from_ber(&hex!("02 01 00")).is_err());
134
    }
135
136
    #[test]
137
    fn debug_from_ber_sequence_indefinite() {
138
        let input = &hex!("30 80 02 03 01 00 01 00 00");
139
        let (rem, result) = Sequence::from_ber(input).expect("parsing failed");
140
        assert_eq!(result.as_ref(), &input[2..7]);
141
        assert_eq!(rem, &[]);
142
        eprintln!("--");
143
        let (rem, result) = <Vec<u32>>::from_ber(input).expect("parsing failed");
144
        assert_eq!(&result, &[65537]);
145
        assert_eq!(rem, &[]);
146
    }
147
148
    #[test]
149
    fn debug_from_ber_sequence_of() {
150
        // parsing failure (wrong type)
151
        let input = &hex!("30 03 01 01 00");
152
        eprintln!("--");
153
        let _ = <SequenceOf<u32>>::from_ber(input).expect_err("parsing should fail");
154
        eprintln!("--");
155
        let _ = <Vec<u32>>::from_ber(input).expect_err("parsing should fail");
156
    }
157
158
    #[test]
159
    fn debug_from_ber_u32() {
160
        assert!(u32::from_ber(&hex!("02 01 01")).is_ok());
161
    }
162
163
    #[test]
164
    fn debug_from_der_any() {
165
        assert!(Any::from_der(&hex!("01 01 ff")).is_ok());
166
    }
167
168
    #[test]
169
    fn debug_from_der_bool() {
170
        eprintln!("** first test is ok**");
171
        assert!(<bool>::from_der(&hex!("01 01 ff")).is_ok());
172
        eprintln!("** second test fails when parsing ANY (eof)**");
173
        assert!(<bool>::from_der(&hex!("01 02 ff")).is_err());
174
        eprintln!("** second test fails when checking DER constraints**");
175
        assert!(<bool>::from_der(&hex!("01 01 f0")).is_err());
176
        eprintln!("** second test fails during TryFrom**");
177
        assert!(<bool>::from_der(&hex!("01 02 ff ff")).is_err());
178
    }
179
180
    #[test]
181
    fn debug_from_der_failures() {
182
        use crate::Sequence;
183
184
        // parsing any failed
185
        eprintln!("--");
186
        assert!(u16::from_der(&hex!("ff 00")).is_err());
187
        // Indefinite length
188
        eprintln!("--");
189
        assert!(u16::from_der(&hex!("30 80 00 00")).is_err());
190
        // DER constraints failed
191
        eprintln!("--");
192
        assert!(bool::from_der(&hex!("01 01 7f")).is_err());
193
        // Incomplete sequence
194
        eprintln!("--");
195
        let _ = Sequence::from_der(&hex!("30 81 04 00 00"));
196
    }
197
198
    #[test]
199
    fn debug_from_der_sequence() {
200
        // parsing OK, recursive
201
        let input = &hex!("30 08 02 03 01 00 01 02 01 01");
202
        let (rem, result) = <Vec<u32>>::from_der(input).expect("parsing failed");
203
        assert_eq!(&result, &[65537, 1]);
204
        assert_eq!(rem, &[]);
205
    }
206
207
    #[test]
208
    fn debug_from_der_sequence_fail() {
209
        // tag is wrong
210
        let input = &hex!("31 03 01 01 44");
211
        let _ = <Vec<bool>>::from_der(input).expect_err("parsing should fail");
212
        // sequence is ok but contraint fails on element
213
        let input = &hex!("30 03 01 01 44");
214
        let _ = <Vec<bool>>::from_der(input).expect_err("parsing should fail");
215
    }
216
217
    #[test]
218
    fn debug_from_der_sequence_of() {
219
        use crate::SequenceOf;
220
        // parsing failure (wrong type)
221
        let input = &hex!("30 03 01 01 00");
222
        eprintln!("--");
223
        let _ = <SequenceOf<u32>>::from_der(input).expect_err("parsing should fail");
224
        eprintln!("--");
225
        let _ = <Vec<u32>>::from_der(input).expect_err("parsing should fail");
226
    }
227
228
    #[test]
229
    fn debug_from_der_set_fail() {
230
        // set is ok but contraint fails on element
231
        let input = &hex!("31 03 01 01 44");
232
        let _ = <BTreeSet<bool>>::from_der(input).expect_err("parsing should fail");
233
    }
234
235
    #[test]
236
    fn debug_from_der_set_of() {
237
        use crate::SetOf;
238
        use alloc::collections::BTreeSet;
239
240
        // parsing failure (wrong type)
241
        let input = &hex!("31 03 01 01 00");
242
        eprintln!("--");
243
        let _ = <SetOf<u32>>::from_der(input).expect_err("parsing should fail");
244
        eprintln!("--");
245
        let _ = <BTreeSet<u32>>::from_der(input).expect_err("parsing should fail");
246
        eprintln!("--");
247
        let _ = <HashSet<u32>>::from_der(input).expect_err("parsing should fail");
248
    }
249
250
    #[test]
251
    fn debug_from_der_string_ok() {
252
        let input = &hex!("0c 0a 53 6f 6d 65 2d 53 74 61 74 65");
253
        let (rem, result) = Utf8String::from_der(input).expect("parsing failed");
254
        assert_eq!(result.as_ref(), "Some-State");
255
        assert_eq!(rem, &[]);
256
    }
257
258
    #[test]
259
    fn debug_from_der_string_fail() {
260
        // wrong charset
261
        let input = &hex!("12 03 41 42 43");
262
        let _ = NumericString::from_der(input).expect_err("parsing should fail");
263
    }
264
}