Coverage Report

Created: 2025-07-23 07:29

/rust/registry/src/index.crates.io-6f17d22bba15001f/der-parser-8.2.0/src/ber/integer.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::error::*;
2
3
/// Decode an unsigned integer into a big endian byte slice with all leading
4
/// zeroes removed.
5
///
6
/// Returns a byte array of the requested size containing a big endian integer.
7
2.27k
fn remove_zeroes(bytes: &[u8]) -> Result<&[u8], BerError> {
8
2.27k
    // skip leading 0s
9
2.27k
    match bytes {
10
2.27k
        // [] => Err(BerError::DerConstraintFailed),
11
2.27k
        [0] => Ok(bytes),
12
        // [0, byte, ..] if *byte < 0x80 => Err(BerError::DerConstraintFailed),
13
        // [0, rest @ ..] => Ok(&rest),
14
860
        [0, rest @ ..] => remove_zeroes(rest),
15
        // [byte, ..] if *byte >= 0x80 => Err(BerError::IntegerTooLarge),
16
785
        _ => Ok(bytes),
17
    }
18
2.27k
}
19
20
// XXX const generics require rustc >= 1.51
21
// /// Decode an unsigned integer into a byte array of the requested size
22
// /// containing a big endian integer.
23
// pub(crate) fn decode_array_uint<const N: usize>(bytes: &[u8]) -> Result<[u8; N], BerError> {
24
//     // Check if MSB is set *before* leading zeroes
25
//     if is_highest_bit_set(bytes) {
26
//         return Err(BerError::IntegerNegative);
27
//     }
28
//     let input = remove_zeroes(bytes)?;
29
30
//     if input.len() > N {
31
//         return Err(BerError::IntegerTooLarge);
32
//     }
33
34
//     // Input has leading zeroes removed, so we need to add them back
35
//     let mut output = [0u8; N];
36
//     assert!(input.len() <= N);
37
//     output[N.saturating_sub(input.len())..].copy_from_slice(input);
38
//     Ok(output)
39
// }
40
41
0
pub(crate) fn decode_array_uint8(bytes: &[u8]) -> Result<[u8; 8], BerError> {
42
0
    // Check if MSB is set *before* leading zeroes
43
0
    if is_highest_bit_set(bytes) {
44
0
        return Err(BerError::IntegerNegative);
45
0
    }
46
0
    let input = remove_zeroes(bytes)?;
47
48
0
    if input.len() > 8 {
49
0
        return Err(BerError::IntegerTooLarge);
50
0
    }
51
0
52
0
    // Input has leading zeroes removed, so we need to add them back
53
0
    let mut output = [0u8; 8];
54
0
    assert!(input.len() <= 8);
55
0
    output[8_usize.saturating_sub(input.len())..].copy_from_slice(input);
56
0
    Ok(output)
57
0
}
58
59
1.43k
pub(crate) fn decode_array_uint4(bytes: &[u8]) -> Result<[u8; 4], BerError> {
60
1.43k
    // Check if MSB is set *before* leading zeroes
61
1.43k
    if is_highest_bit_set(bytes) {
62
15
        return Err(BerError::IntegerNegative);
63
1.41k
    }
64
1.41k
    let input = remove_zeroes(bytes)?;
65
66
1.41k
    if input.len() > 4 {
67
13
        return Err(BerError::IntegerTooLarge);
68
1.40k
    }
69
1.40k
70
1.40k
    // Input has leading zeroes removed, so we need to add them back
71
1.40k
    let mut output = [0u8; 4];
72
1.40k
    assert!(input.len() <= 4);
73
1.40k
    output[4_usize.saturating_sub(input.len())..].copy_from_slice(input);
74
1.40k
    Ok(output)
75
1.43k
}
76
77
// XXX const generics require rustc >= 1.51
78
// /// Decode an unsigned integer of the specified size.
79
// ///
80
// /// Returns a byte array of the requested size containing a big endian integer.
81
// pub(crate) fn decode_array_int<const N: usize>(input: &[u8]) -> Result<[u8; N], BerError> {
82
//     let input = remove_zeroes(input)?;
83
84
//     if input.len() > N {
85
//         return Err(BerError::IntegerTooLarge);
86
//     }
87
88
//     // any.tag().assert_eq(Tag::Integer)?;
89
//     let mut output = [0xFFu8; N];
90
//     let offset = N.saturating_sub(input.len());
91
//     output[offset..].copy_from_slice(input);
92
//     Ok(output)
93
// }
94
95
0
pub(crate) fn decode_array_int8(input: &[u8]) -> Result<[u8; 8], BerError> {
96
0
    let input = remove_zeroes(input)?;
97
98
0
    if input.len() > 8 {
99
0
        return Err(BerError::IntegerTooLarge);
100
0
    }
101
0
102
0
    // any.tag().assert_eq(Tag::Integer)?;
103
0
    let mut output = [0xFFu8; 8];
104
0
    let offset = 8_usize.saturating_sub(input.len());
105
0
    output[offset..].copy_from_slice(input);
106
0
    Ok(output)
107
0
}
108
109
0
pub(crate) fn decode_array_int4(input: &[u8]) -> Result<[u8; 4], BerError> {
110
0
    let input = remove_zeroes(input)?;
111
112
0
    if input.len() > 4 {
113
0
        return Err(BerError::IntegerTooLarge);
114
0
    }
115
0
116
0
    // any.tag().assert_eq(Tag::Integer)?;
117
0
    let mut output = [0xFFu8; 4];
118
0
    let offset = 4_usize.saturating_sub(input.len());
119
0
    output[offset..].copy_from_slice(input);
120
0
    Ok(output)
121
0
}
122
123
/// Is the highest bit of the first byte in the slice 1? (if present)
124
#[inline]
125
1.43k
pub(crate) fn is_highest_bit_set(bytes: &[u8]) -> bool {
126
1.43k
    bytes
127
1.43k
        .first()
128
1.43k
        .map(|byte| byte & 0b10000000 != 0)
129
1.43k
        .unwrap_or(false)
130
1.43k
}