Coverage Report

Created: 2026-08-13 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mp4san/webpsan/src/parse/integers.rs
Line
Count
Source
1
#![allow(missing_docs)]
2
3
use std::mem::size_of;
4
use std::num::NonZeroU32;
5
6
use bitflags::Flags;
7
use bytes::{Buf, BufMut};
8
9
use mediasan_common::error::WhileParsingType;
10
use mediasan_common::parse::FourCC;
11
use mediasan_common::{ensure_attach, report_attach, Result, ResultExt};
12
13
use super::ParseError;
14
15
pub trait WebmPrim: Sized {
16
    const ENCODED_LEN: u32;
17
    fn parse<B: Buf>(buf: B) -> Result<Self, ParseError>;
18
    fn put_buf<B: BufMut>(&self, buf: B);
19
}
20
21
pub trait WebmFlags: Flags {}
22
23
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
24
pub struct U24(u32);
25
26
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
27
pub struct OneBasedU24(NonZeroU32);
28
29
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
30
pub struct Reserved<const LEN: u32>(());
31
32
//
33
// WebMPrim impls
34
//
35
36
macro_rules! webm_int {
37
    ($($ty:ty => ($get_fun:ident, $put_fun:ident)),+ $(,)?) => {
38
        $(impl WebmPrim for $ty {
39
40
            const ENCODED_LEN: u32 = size_of::<Self>() as u32;
41
42
1.39k
            fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
43
1.39k
                ensure_attach!(
44
1.39k
                    buf.remaining() >= Self::ENCODED_LEN as usize,
45
0
                    ParseError::TruncatedChunk,
46
0
                    WhileParsingType::new::<Self>(),
47
                );
48
1.39k
                Ok(buf.$get_fun())
49
1.39k
            }
<u16 as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>
Line
Count
Source
42
699
            fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
43
699
                ensure_attach!(
44
699
                    buf.remaining() >= Self::ENCODED_LEN as usize,
45
0
                    ParseError::TruncatedChunk,
46
0
                    WhileParsingType::new::<Self>(),
47
                );
48
699
                Ok(buf.$get_fun())
49
699
            }
<u32 as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>
Line
Count
Source
42
699
            fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
43
699
                ensure_attach!(
44
699
                    buf.remaining() >= Self::ENCODED_LEN as usize,
45
0
                    ParseError::TruncatedChunk,
46
0
                    WhileParsingType::new::<Self>(),
47
                );
48
699
                Ok(buf.$get_fun())
49
699
            }
50
51
0
            fn put_buf<B: BufMut>(&self, mut buf: B) {
52
0
                buf.$put_fun(*self)
53
0
            }
Unexecuted instantiation: <u16 as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut>
Unexecuted instantiation: <u32 as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut>
54
        })+
55
    };
56
}
57
58
webm_int! {
59
    u8 => (get_u8, put_u8),
60
    u16 => (get_u16, put_u16_le),
61
    u32 => (get_u32_le, put_u32_le),
62
    u64 => (get_u64_le, put_u64_le),
63
    i8 => (get_i8, put_i8),
64
    i16 => (get_i16_le, put_i16_le),
65
    i32 => (get_i32_le, put_i32_le),
66
    i64 => (get_i64_le, put_i64_le),
67
}
68
69
impl WebmPrim for FourCC {
70
    const ENCODED_LEN: u32 = 4;
71
72
    fn parse<B: Buf>(buf: B) -> Result<Self, ParseError> {
73
        ensure_attach!(
74
            buf.remaining() >= Self::ENCODED_LEN as usize,
75
            ParseError::TruncatedChunk,
76
            WhileParsingType::new::<Self>(),
77
        );
78
        Ok(FourCC::parse(buf))
79
    }
80
81
    fn put_buf<B: BufMut>(&self, buf: B) {
82
        FourCC::put_buf(self, buf)
83
    }
84
}
85
86
//
87
// WebmFlags impls
88
//
89
90
impl<T: WebmFlags> WebmPrim for T
91
where
92
    T::Bits: TryFrom<u64> + Into<u64>,
93
{
94
    const ENCODED_LEN: u32 = size_of::<<Self as Flags>::Bits>() as u32;
95
96
11.6k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
97
11.6k
        ensure_attach!(
98
11.6k
            buf.remaining() >= Self::ENCODED_LEN as usize,
99
0
            ParseError::TruncatedChunk,
100
0
            WhileParsingType::new::<Self>(),
101
        );
102
11.6k
        let value = buf.get_uint_le(Self::ENCODED_LEN as usize);
103
11.6k
        let value = value.try_into().unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: <webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut>::{closure#0}
Unexecuted instantiation: <webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#0}
Unexecuted instantiation: <webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#0}
104
11.6k
        Self::from_bits(value)
105
11.6k
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
<webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut>::{closure#1}
Line
Count
Source
105
14
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
<webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#1}
Line
Count
Source
105
19
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
<webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>::{closure#1}
Line
Count
Source
105
6
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
106
11.6k
            .while_parsing_type()
107
11.6k
    }
<webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>
Line
Count
Source
96
5.74k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
97
5.74k
        ensure_attach!(
98
5.74k
            buf.remaining() >= Self::ENCODED_LEN as usize,
99
0
            ParseError::TruncatedChunk,
100
0
            WhileParsingType::new::<Self>(),
101
        );
102
5.74k
        let value = buf.get_uint_le(Self::ENCODED_LEN as usize);
103
5.74k
        let value = value.try_into().unwrap_or_else(|_| unreachable!());
104
5.74k
        Self::from_bits(value)
105
5.74k
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
106
5.74k
            .while_parsing_type()
107
5.74k
    }
<webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut bytes::bytes_mut::BytesMut>
Line
Count
Source
96
2.41k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
97
2.41k
        ensure_attach!(
98
2.41k
            buf.remaining() >= Self::ENCODED_LEN as usize,
99
0
            ParseError::TruncatedChunk,
100
0
            WhileParsingType::new::<Self>(),
101
        );
102
2.41k
        let value = buf.get_uint_le(Self::ENCODED_LEN as usize);
103
2.41k
        let value = value.try_into().unwrap_or_else(|_| unreachable!());
104
2.41k
        Self::from_bits(value)
105
2.41k
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
106
2.41k
            .while_parsing_type()
107
2.41k
    }
<webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::parse::<&mut &mut bytes::bytes_mut::BytesMut>
Line
Count
Source
96
3.44k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
97
3.44k
        ensure_attach!(
98
3.44k
            buf.remaining() >= Self::ENCODED_LEN as usize,
99
0
            ParseError::TruncatedChunk,
100
0
            WhileParsingType::new::<Self>(),
101
        );
102
3.44k
        let value = buf.get_uint_le(Self::ENCODED_LEN as usize);
103
3.44k
        let value = value.try_into().unwrap_or_else(|_| unreachable!());
104
3.44k
        Self::from_bits(value)
105
3.44k
            .ok_or_else(|| report_attach!(ParseError::InvalidInput, "non-zero reserved bits"))
106
3.44k
            .while_parsing_type()
107
3.44k
    }
108
109
0
    fn put_buf<B: BufMut>(&self, mut buf: B) {
110
0
        buf.put_uint(self.bits().into(), Self::ENCODED_LEN as usize);
111
0
    }
Unexecuted instantiation: <webpsan::parse::anmf::AnmfFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut>
Unexecuted instantiation: <webpsan::parse::alph::AlphFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut dyn bytes::buf::buf_mut::BufMut>
Unexecuted instantiation: <webpsan::parse::vp8x::Vp8xFlags as webpsan::parse::integers::WebmPrim>::put_buf::<&mut &mut dyn bytes::buf::buf_mut::BufMut>
112
}
113
114
//
115
// U24 impls
116
//
117
118
impl U24 {
119
11.4k
    pub fn get(&self) -> u32 {
120
11.4k
        self.0
121
11.4k
    }
122
}
123
124
impl WebmPrim for U24 {
125
    const ENCODED_LEN: u32 = 3;
126
127
17.2k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
128
17.2k
        ensure_attach!(
129
17.2k
            buf.remaining() >= Self::ENCODED_LEN as usize,
130
0
            ParseError::TruncatedChunk,
131
0
            WhileParsingType::new::<Self>(),
132
        );
133
17.2k
        Ok(Self(buf.get_uint_le(Self::ENCODED_LEN as usize) as u32))
134
17.2k
    }
135
136
0
    fn put_buf<B: BufMut>(&self, mut buf: B) {
137
0
        buf.put_uint_le(self.0.into(), Self::ENCODED_LEN as usize)
138
0
    }
139
}
140
141
//
142
// OneBasedU24 impls
143
//
144
145
impl OneBasedU24 {
146
31.5k
    pub fn get(&self) -> NonZeroU32 {
147
31.5k
        self.0
148
31.5k
    }
149
}
150
151
impl WebmPrim for OneBasedU24 {
152
    const ENCODED_LEN: u32 = 3;
153
154
18.3k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
155
18.3k
        ensure_attach!(
156
18.3k
            buf.remaining() >= Self::ENCODED_LEN as usize,
157
0
            ParseError::TruncatedChunk,
158
0
            WhileParsingType::new::<Self>(),
159
        );
160
18.3k
        let value = NonZeroU32::MIN.saturating_add(buf.get_uint_le(Self::ENCODED_LEN as usize) as u32);
161
18.3k
        Ok(Self(value))
162
18.3k
    }
163
164
0
    fn put_buf<B: BufMut>(&self, mut buf: B) {
165
0
        buf.put_uint_le(u64::from(self.0.get()) - 1, Self::ENCODED_LEN as usize);
166
0
    }
167
}
168
169
//
170
// Reserved impls
171
//
172
173
impl<const LEN: u32> WebmPrim for Reserved<LEN> {
174
    const ENCODED_LEN: u32 = LEN;
175
176
3.44k
    fn parse<B: Buf>(mut buf: B) -> Result<Self, ParseError> {
177
13.7k
        for _ in 0..LEN {
178
10.3k
            ensure_attach!(
179
10.3k
                buf.get_u8() == 0,
180
22
                ParseError::InvalidInput,
181
                "non-zero reserved bits",
182
22
                WhileParsingType::new::<Self>(),
183
            );
184
        }
185
3.42k
        Ok(Self(()))
186
3.44k
    }
187
188
0
    fn put_buf<B: BufMut>(&self, mut buf: B) {
189
0
        for _ in 0..LEN {
190
0
            buf.put_u8(0);
191
0
        }
192
0
    }
193
}