refactor(rust/trezor-thp): error constructors
What changed, and why it matters
This commit is a straightforward internal code cleanup in Trezor's Rust transport protocol library. It replaces direct creation of error values with calls to new helper functions (constructors) so developers can set breakpoints to trace where errors originate. It also removes one unused error variant (OutOfBounds) and maps those cases to MalformedData instead. There is no functional security change or bug fix visible in the diff.
No security action required. Treat as normal code hygiene/refactor.
Security signals we found
No security-relevant functional change
Refactor only: error constructor call style
Removal of unused OutOfBounds error variant
Log wording correction: 'digest' -> 'checksum'
Evidence from the diff
The change refactors the Error enum in rust/trezor-thp/src/error.rs by adding const fn constructors (unexpected_input, not_ready, malformed_data, invalid_checksum, insufficient_buffer, crypto_error). All call sites across the crate are updated from Error::Variant to Error::variant() or Error::variant (for ok_or_else closures). The OutOfBounds variant is removed, and previous uses now return Error::MalformedData. A log message is updated from ‘invalid digest’ to ‘invalid checksum’ to match the error name. No protocol behavior, validation logic, or cryptographic handling is altered.
Changed components
rust/trezor-thp/src/error.rsrust/trezor-thp/src/alternating_bit.rsrust/trezor-thp/src/channel/host.rsrust/trezor-thp/src/channel/mod.rsrust/trezor-thp/src/channel/noise.rsrust/trezor-thp/src/control_byte.rsrust/trezor-thp/src/fragment.rsrust/trezor-thp/src/header.rsInspect captured patch +102 / −72
diff --git a/rust/trezor-thp/src/alternating_bit.rs b/rust/trezor-thp/src/alternating_bit.rs
index 8a5a1536..1739ab8c 100644
--- a/rust/trezor-thp/src/alternating_bit.rs
+++ b/rust/trezor-thp/src/alternating_bit.rs
@@ -46,7 +46,7 @@ impl TryFrom<&[u8]> for SyncBits {
type Error = Error;
fn try_from(bytes: &[u8]) -> Result<Self, Error> {
- let first_byte = bytes.first().ok_or(Error::MalformedData)?;
+ let first_byte = bytes.first().ok_or_else(Error::malformed_data)?;
Ok(Self::from(*first_byte))
}
}
diff --git a/rust/trezor-thp/src/channel/host.rs b/rust/trezor-thp/src/channel/host.rs
index 284405e1..e75599d0 100644
--- a/rust/trezor-thp/src/channel/host.rs
+++ b/rust/trezor-thp/src/channel/host.rs
@@ -100,7 +100,7 @@ impl<C: CredentialStore, B: Backend> ChannelOpen<C, B> {
}
_ => {
log::error!("Unexpected handshake state.");
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
}
Ok(())
@@ -114,8 +114,8 @@ impl<C: CredentialStore, B: Backend> ChannelOpen<C, B> {
};
let (cid, device_properties) = parse_u16(payload)?;
self.channel.channel_id = cid;
- self.device_properties =
- heapless::Vec::from_slice(device_properties).map_err(|_| Error::InsufficientBuffer)?;
+ self.device_properties = heapless::Vec::from_slice(device_properties)
+ .map_err(|_| Error::insufficient_buffer())?;
Ok(ControlFlow::Continue(()))
}
@@ -144,7 +144,7 @@ impl<C: CredentialStore, B: Backend> ChannelOpen<C, B> {
self.internal_buffer
.resize(self.internal_buffer.capacity(), 0u8)
.unwrap();
- let noise = self.noise.as_mut().ok_or(Error::UnexpectedInput)?;
+ let noise = self.noise.as_mut().ok_or_else(Error::unexpected_input)?;
let (nc, msg) =
noise.complete_pairing(&mut self.cred_store, &mut self.internal_buffer, payload_len)?;
self.channel.noise = Some(nc);
@@ -191,7 +191,7 @@ impl<C: CredentialStore, B: Backend> ChannelOpen<C, B> {
/// Transition into the pairing phase.
pub fn complete(self) -> Result<ChannelPairing<B>, Error> {
if self.is_broadcast() || self.channel.noise.is_none() {
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
log::debug!("Handshake complete.");
Ok(match self.state {
@@ -201,7 +201,7 @@ impl<C: CredentialStore, B: Backend> ChannelOpen<C, B> {
pairing_state: ps,
is_finished: false,
},
- _ => return Err(Error::UnexpectedInput),
+ _ => return Err(Error::unexpected_input()),
})
}
}
@@ -305,7 +305,7 @@ impl<B: Backend> ChannelPairing<B> {
pub fn complete(self) -> Result<Channel<Host, B>, Error> {
if !self.is_finished {
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
log::debug!("Pairing and credentials complete, begin application level transport.");
Ok(self.channel)
@@ -344,7 +344,7 @@ impl<B: Backend> ChannelIO for ChannelPairing<B> {
let (sid, message_type, message) = self.channel.message_out(receive_buffer)?;
if sid != 0 {
log::error!("Invalid session id in pairing phase.");
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
}
if message_type == MESSAGE_TYPE_END_RESPONSE {
self.is_finished = true;
diff --git a/rust/trezor-thp/src/channel/mod.rs b/rust/trezor-thp/src/channel/mod.rs
index a3435356..bf4b63d0 100644
--- a/rust/trezor-thp/src/channel/mod.rs
+++ b/rust/trezor-thp/src/channel/mod.rs
@@ -31,7 +31,7 @@ impl Nonce {
bytes
.split_first_chunk::<{ Nonce::LEN }>()
.map(|(n, p)| (Nonce(*n), p))
- .ok_or(Error::MalformedData)
+ .ok_or_else(Error::malformed_data)
}
pub fn as_slice(&self) -> &[u8] {
@@ -62,7 +62,7 @@ impl TryFrom<&[u8]> for PairingState {
[0] => Self::Unpaired,
[1] => Self::Paired,
[2] => Self::PairedAutoconnect,
- _ => return Err(Error::MalformedData),
+ _ => return Err(Error::malformed_data()),
})
}
}
@@ -107,7 +107,7 @@ impl<R: Role, B: Backend> Channel<R, B> {
}
fn noise(&mut self) -> Result<&mut NoiseCiphers<B>> {
- self.noise.as_mut().ok_or(Error::UnexpectedInput)
+ self.noise.as_mut().ok_or_else(Error::unexpected_input)
}
fn is_broadcast(&self) -> bool {
@@ -124,12 +124,12 @@ impl<R: Role, B: Backend> Channel<R, B> {
fn raw_in(&mut self, header: Header<R>, send_buffer: &[u8]) -> Result<()> {
let ChannelState::Idle = self.state else {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
};
let sb = if self.is_broadcast() {
SyncBits::new()
} else {
- self.sync.send_start().ok_or(Error::NotReady)?
+ self.sync.send_start().ok_or_else(Error::not_ready)?
};
let frag = Fragmenter::new(header, sb, send_buffer)?;
self.state = ChannelState::Sending(frag);
@@ -139,16 +139,16 @@ impl<R: Role, B: Backend> Channel<R, B> {
fn raw_out(&mut self, receive_buffer: &[u8]) -> Result<(Header<R>, usize)> {
let has_cid = !self.is_broadcast();
let ChannelState::Receiving(r) = &mut self.state else {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
};
if !r.is_done() {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
}
let len = match r.verify(receive_buffer) {
Ok(len) => len,
Err(e) => {
log::warn!(
- "[{}] Reassembled message with invalid digest.",
+ "[{}] Reassembled message with invalid checksum.",
self.channel_id
);
return Err(e);
@@ -194,7 +194,7 @@ impl<R: Role, B: Backend> Channel<R, B> {
}
log::error!("[{}] Peer sent unknown error.", self.channel_id);
self.state = ChannelState::Failed(None);
- Err(Error::MalformedData)
+ Err(Error::malformed_data())
}
fn handle_init(
@@ -368,11 +368,11 @@ pub trait ChannelIO {
send_buffer: &mut [u8],
) -> Result<()> {
if !self.message_in_ready() {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
}
let plaintext_len = message.len() + APP_HEADER_LEN;
if send_buffer.len() < plaintext_len {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
send_buffer[0] = session_id;
send_buffer[1..3].copy_from_slice(&message_type.to_be_bytes());
@@ -446,11 +446,11 @@ impl<R: Role, B: Backend> ChannelIO for Channel<R, B> {
return Ok(());
}
let ChannelState::Sending(f) = &mut self.state else {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
};
let written = f.next(send_buffer, packet_buffer)?;
if !written {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
}
if f.is_done() {
if self.is_broadcast() {
@@ -475,11 +475,11 @@ impl<R: Role, B: Backend> ChannelIO for Channel<R, B> {
fn message_in(&mut self, plaintext_len: usize, send_buffer: &mut [u8]) -> Result<()> {
if !self.message_in_ready() {
- return Err(Error::NotReady);
+ return Err(Error::not_ready());
}
let encrypted_len = plaintext_len + TAG_LEN;
if send_buffer.len() < encrypted_len {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
self.noise()?.encrypt(send_buffer, plaintext_len)?;
let header = Header::new_encrypted(self.channel_id, &send_buffer[..encrypted_len])?;
@@ -499,7 +499,7 @@ impl<R: Role, B: Backend> ChannelIO for Channel<R, B> {
"[{}] Invalid message type, expecting EncryptedTransport.",
self.channel_id
);
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
}
let receive_buffer = match self.noise()?.decrypt(receive_buffer) {
@@ -514,7 +514,9 @@ impl<R: Role, B: Backend> ChannelIO for Channel<R, B> {
log::error!("[{}] Incoming message too short.", self.channel_id);
// fails on the next two lines
}
- let (session_id, rest) = receive_buffer.split_first().ok_or(Error::MalformedData)?;
+ let (session_id, rest) = receive_buffer
+ .split_first()
+ .ok_or_else(Error::malformed_data)?;
let (message_type, rest) = parse_u16(rest)?;
Ok((*session_id, message_type, rest))
}
diff --git a/rust/trezor-thp/src/channel/noise.rs b/rust/trezor-thp/src/channel/noise.rs
index 283945aa..b78bf556 100644
--- a/rust/trezor-thp/src/channel/noise.rs
+++ b/rust/trezor-thp/src/channel/noise.rs
@@ -39,7 +39,7 @@ pub struct NoiseCiphers<B: Backend> {
impl<B: Backend> NoiseCiphers<B> {
pub fn encrypt(&mut self, in_out: &mut [u8], plaintext_len: usize) -> Result<(), Error> {
if in_out.len() < plaintext_len + TAG_LEN {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
self.encrypt.encrypt_ad_in_place(&[], in_out, plaintext_len);
Ok(())
@@ -47,11 +47,11 @@ impl<B: Backend> NoiseCiphers<B> {
pub fn decrypt(&mut self, in_out: &mut [u8]) -> Result<usize, Error> {
if in_out.len() < TAG_LEN {
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
}
self.decrypt
.decrypt_ad_in_place(&[], in_out, in_out.len())
- .map_err(|()| Error::CryptoError)
+ .map_err(|()| Error::crypto_error())
}
pub fn handshake_hash(&self) -> &[u8; HANDSHAKE_HASH_LEN] {
@@ -76,7 +76,7 @@ impl<B: Backend> NoiseHandshake<Host, B> {
/*rs=*/ None,
);
let len = hss.get_next_message_overhead() + payload.len();
- let dest = dest.get_mut(..len).ok_or(Error::InsufficientBuffer)?;
+ let dest = dest.get_mut(..len).ok_or_else(Error::insufficient_buffer)?;
hss.write_message(payload, dest)?;
let new = NoiseHandshake {
hss,
@@ -93,28 +93,30 @@ impl<B: Backend> NoiseHandshake<Host, B> {
) -> Result<(NoiseCiphers<B>, &'a [u8]), Error> {
if incoming_len != self.hss.get_next_message_overhead() {
log::error!("Unexpected message length during handshake.");
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
}
let incoming = buffer
.get(..incoming_len)
- .ok_or(Error::InsufficientBuffer)?;
+ .ok_or_else(Error::insufficient_buffer)?;
self.hss.read_message(incoming, &mut [])?;
// Look up static key based on remote keys, or generate a new one.
- let remote_static_key = self.hss.get_rs().ok_or(Error::CryptoError)?;
- let remote_ephemeral_key = self.hss.get_re().ok_or(Error::CryptoError)?;
+ let remote_static_key = self.hss.get_rs().ok_or_else(Error::crypto_error)?;
+ let remote_ephemeral_key = self.hss.get_re().ok_or_else(Error::crypto_error)?;
let (local_static, pairing_credential) =
Self::credential_from_store(cred_store, &remote_ephemeral_key, &remote_static_key)?;
self.hss.set_s(local_static);
buffer.fill(0);
let len = self.hss.get_next_message_overhead() + pairing_credential.len();
- let dest = buffer.get_mut(..len).ok_or(Error::InsufficientBuffer)?;
+ let dest = buffer
+ .get_mut(..len)
+ .ok_or_else(Error::insufficient_buffer)?;
self.hss
.write_message(pairing_credential.as_slice(), dest)?;
if !self.hss.completed() {
log::error!("Handshake not completed.");
- return Err(Error::CryptoError);
+ return Err(Error::crypto_error());
}
let (encrypt, decrypt) = self.hss.get_ciphers();
let mut handshake_hash = [0u8; HANDSHAKE_HASH_LEN];
@@ -141,7 +143,7 @@ impl<B: Backend> NoiseHandshake<Host, B> {
if let Some(found) = result {
let found_key = <DHPrivKey<B> as U8Array>::from_slice(found.local_static_privkey);
let found_credential = heapless::Vec::from_slice(found.auth_credential)
- .map_err(|_| Error::InsufficientBuffer)?;
+ .map_err(|_| Error::insufficient_buffer())?;
return Ok((found_key, found_credential));
}
buf.clear();
diff --git a/rust/trezor-thp/src/control_byte.rs b/rust/trezor-thp/src/control_byte.rs
index 6313fcaf..bcd8017c 100644
--- a/rust/trezor-thp/src/control_byte.rs
+++ b/rust/trezor-thp/src/control_byte.rs
@@ -92,7 +92,7 @@ impl TryFrom<&[u8]> for ControlByte {
type Error = Error;
fn try_from(bytes: &[u8]) -> Result<Self, Error> {
- let first_byte = bytes.first().ok_or(Error::MalformedData)?;
+ let first_byte = bytes.first().ok_or_else(Error::malformed_data)?;
Ok(Self::from(*first_byte))
}
}
diff --git a/rust/trezor-thp/src/error.rs b/rust/trezor-thp/src/error.rs
index e7b484e5..b80a3bfb 100644
--- a/rust/trezor-thp/src/error.rs
+++ b/rust/trezor-thp/src/error.rs
@@ -36,7 +36,7 @@ impl TryFrom<u8> for TransportError {
2 => Self::UnallocatedChannel,
3 => Self::DecryptionFailed,
5 => Self::DeviceLocked,
- _ => return Err(Error::OutOfBounds),
+ _ => return Err(Error::malformed_data()),
})
}
}
@@ -46,7 +46,7 @@ impl TryFrom<&[u8]> for TransportError {
fn try_from(val: &[u8]) -> Result<Self> {
val.first()
- .ok_or(Error::MalformedData)
+ .ok_or_else(Error::malformed_data)
.and_then(|b| TransportError::try_from(*b))
}
}
@@ -54,8 +54,6 @@ impl TryFrom<&[u8]> for TransportError {
#[cfg_attr(any(test, debug_assertions), derive(Debug))]
#[derive(PartialEq, Eq)]
pub enum Error {
- /// Numeric field has forbidden value.
- OutOfBounds,
/// Invalid data/operation from crate user.
UnexpectedInput,
/// Channel is not ready to send another message, or there is no message ready to be passed
@@ -74,11 +72,37 @@ pub enum Error {
impl From<NoiseError> for Error {
fn from(val: NoiseError) -> Self {
match val.kind() {
- NoiseErrorKind::DH | NoiseErrorKind::Decryption => Self::CryptoError,
+ NoiseErrorKind::DH | NoiseErrorKind::Decryption => Self::crypto_error(),
NoiseErrorKind::NeedPSK => panic!(),
- NoiseErrorKind::TooShort => Self::MalformedData,
+ NoiseErrorKind::TooShort => Self::malformed_data(),
}
}
}
pub type Result<T> = core::result::Result<T, Error>;
+
+impl Error {
+ pub const fn unexpected_input() -> Self {
+ Self::UnexpectedInput
+ }
+
+ pub const fn not_ready() -> Self {
+ Self::NotReady
+ }
+
+ pub const fn malformed_data() -> Self {
+ Self::MalformedData
+ }
+
+ pub const fn invalid_checksum() -> Self {
+ Self::InvalidChecksum
+ }
+
+ pub const fn insufficient_buffer() -> Self {
+ Self::InsufficientBuffer
+ }
+
+ pub const fn crypto_error() -> Self {
+ Self::CryptoError
+ }
+}
diff --git a/rust/trezor-thp/src/fragment.rs b/rust/trezor-thp/src/fragment.rs
index 017d1445..d5823fb1 100644
--- a/rust/trezor-thp/src/fragment.rs
+++ b/rust/trezor-thp/src/fragment.rs
@@ -17,7 +17,7 @@ pub struct Fragmenter<R: Role> {
impl<R: Role> Fragmenter<R> {
pub fn new(header: Header<R>, sync_bits: SyncBits, payload: &[u8]) -> Result<Self> {
if payload.len() + CHECKSUM_LEN != header.payload_len().into() {
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
Ok(Self {
header,
@@ -31,11 +31,11 @@ impl<R: Role> Fragmenter<R> {
pub fn next(&mut self, payload: &[u8], dest: &mut [u8]) -> Result<bool> {
const MIN_PACKET_SIZE: usize = Header::<crate::Device>::new_ping().header_len() + 1;
if dest.len() < MIN_PACKET_SIZE {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
if payload.len() + CHECKSUM_LEN != self.header.payload_len().into() {
// buffer changed since new
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
if self.is_done() {
return Ok(false);
@@ -45,14 +45,14 @@ impl<R: Role> Fragmenter<R> {
let header_len = self
.header
.to_bytes(self.sync_bits, dest)
- .ok_or(Error::UnexpectedInput)?;
+ .ok_or_else(Error::unexpected_input)?;
self.checksum.update(&dest[..header_len]);
header_len
} else {
let cont_header = Header::<R>::new_continuation(self.header.channel_id())?;
cont_header
.to_bytes(SyncBits::new(), dest)
- .ok_or(Error::UnexpectedInput)?
+ .ok_or_else(Error::unexpected_input)?
};
let mut rest = &mut dest[header_len..];
@@ -67,7 +67,9 @@ impl<R: Role> Fragmenter<R> {
if self.offset >= payload.len() && self.crc_offset < CHECKSUM_LEN {
let crc = self.checksum.finalize();
- let crc = crc.get(self.crc_offset..).ok_or(Error::UnexpectedInput)?;
+ let crc = crc
+ .get(self.crc_offset..)
+ .ok_or_else(Error::unexpected_input)?;
let nbytes = crc.len().min(rest.len());
rest[..nbytes].copy_from_slice(&crc[..nbytes]);
self.crc_offset += nbytes;
@@ -95,7 +97,7 @@ impl<R: Role> Fragmenter<R> {
let mut fragmenter = Self::new(header, sb, payload)?;
fragmenter.next(payload, dest)?;
if !fragmenter.is_done() {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
Ok(())
}
@@ -111,12 +113,12 @@ impl<R: Role> Reassembler<R> {
pub fn new(input: &[u8], buffer: &mut [u8]) -> Result<Self> {
let (header, after_header) = Header::parse(input)?;
if header.is_continuation() {
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
let payload_len = header.payload_len().into();
if buffer.len() < payload_len {
- return Err(Error::InsufficientBuffer);
+ return Err(Error::insufficient_buffer());
}
let mut checksum = Crc32::new();
@@ -142,7 +144,7 @@ impl<R: Role> Reassembler<R> {
"[{}] Unexpected initiation packet.",
self.header.channel_id()
);
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
if header.channel_id() != self.header.channel_id() {
@@ -151,12 +153,12 @@ impl<R: Role> Reassembler<R> {
self.header.channel_id(),
header.channel_id()
);
- return Err(Error::OutOfBounds);
+ return Err(Error::malformed_data());
}
let payload_len = self.header.payload_len().into();
if buffer.len() < payload_len {
- return Err(Error::InsufficientBuffer); // buffer changed since new()
+ return Err(Error::insufficient_buffer()); // buffer changed since new()
}
let payload_remaining = payload_len.saturating_sub(self.offset);
@@ -176,18 +178,18 @@ impl<R: Role> Reassembler<R> {
pub fn verify(&self, buffer: &[u8]) -> Result<usize> {
if !self.is_done() {
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
let computed_checksum = self.checksum.finalize();
let length_no_checksum =
usize::from(self.header.payload_len()).saturating_sub(CHECKSUM_LEN);
let received_checksum = *buffer
.get(length_no_checksum..)
- .ok_or(Error::InvalidChecksum)?
+ .ok_or_else(Error::invalid_checksum)?
.first_chunk::<CHECKSUM_LEN>()
- .ok_or(Error::InvalidChecksum)?;
+ .ok_or_else(Error::invalid_checksum)?;
if computed_checksum != received_checksum {
- return Err(Error::InvalidChecksum);
+ return Err(Error::invalid_checksum());
}
Ok(length_no_checksum)
}
@@ -201,7 +203,7 @@ impl<R: Role> Reassembler<R> {
let reassembler = Self::new(buffer, dest)?;
if !reassembler.is_done() {
log::error!("Single packet message expected.");
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
}
let reply_len = reassembler.verify(dest)?;
let header = reassembler.header;
@@ -373,6 +375,6 @@ mod test {
let packet = &[0x04, 0x12, 0x34, 0x00, 0x03, 0x00, 0x00, 0x00];
let mut received = [0u8; MAX_MESSAGE];
let reassembler = Reassembler::<Device>::new(packet, &mut received);
- assert!(matches!(reassembler, Err(Error::OutOfBounds)));
+ assert!(matches!(reassembler, Err(Error::MalformedData)));
}
}
diff --git a/rust/trezor-thp/src/header.rs b/rust/trezor-thp/src/header.rs
index 274a4179..e8ea9d56 100644
--- a/rust/trezor-thp/src/header.rs
+++ b/rust/trezor-thp/src/header.rs
@@ -68,7 +68,7 @@ pub const fn channel_id_valid(channel_id: u16) -> bool {
pub(crate) fn parse_u16(buffer: &[u8]) -> Result<(u16, &[u8])> {
let Some((bytes, rest)) = buffer.split_first_chunk::<2>() else {
log::error!("Packet too short.");
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
};
Ok((u16::from_be_bytes(*bytes), rest))
}
@@ -76,7 +76,7 @@ pub(crate) fn parse_u16(buffer: &[u8]) -> Result<(u16, &[u8])> {
pub(crate) fn parse_cb_channel(buffer: &[u8]) -> Result<(ControlByte, u16, &[u8])> {
let Some((cb, rest)) = buffer.split_first() else {
log::error!("Packet is empty.");
- return Err(Error::MalformedData);
+ return Err(Error::malformed_data());
};
let (channel_id, rest) = parse_u16(rest)?;
Ok((ControlByte::from(*cb), channel_id, rest))
@@ -101,7 +101,7 @@ impl<R: Role> Header<R> {
}
if !channel_id_valid(channel_id) {
log::error!("Invalid channel id {}.", channel_id);
- return Err(Error::OutOfBounds);
+ return Err(Error::malformed_data());
}
if cb.is_continuation() {
return Ok((Header::Continuation { channel_id }, rest));
@@ -109,11 +109,11 @@ impl<R: Role> Header<R> {
let (payload_len, rest) = parse_u16(rest)?;
if payload_len > MAX_PAYLOAD_LEN {
log::error!("Payload length exceeds {}.", MAX_PAYLOAD_LEN);
- return Err(Error::OutOfBounds);
+ return Err(Error::malformed_data());
}
if payload_len < CHECKSUM_LEN {
log::error!("Payload length is less than {}.", CHECKSUM_LEN);
- return Err(Error::OutOfBounds);
+ return Err(Error::malformed_data());
}
// strip padding if there is any
let without_padding = rest.len().min(payload_len.into());
@@ -136,7 +136,7 @@ impl<R: Role> Header<R> {
channel_id,
payload_len
);
- Err(Error::MalformedData)
+ Err(Error::malformed_data())
}
fn parse_single(cb: ControlByte, channel_id: u16, payload_len: u16) -> Result<Option<Self>> {
@@ -164,7 +164,7 @@ impl<R: Role> Header<R> {
Ok(Some(res))
} else {
log::error!("Unexpected payload length.");
- Err(Error::MalformedData)
+ Err(Error::malformed_data())
}
}
@@ -291,13 +291,13 @@ impl<R: Role> Header<R> {
}
}
log::error!("Cannot construct: message too long {}.", payload.len());
- Err(Error::UnexpectedInput)
+ Err(Error::unexpected_input())
}
fn validate_channel(channel_id: u16) -> Result<u16> {
if !channel_id_valid(channel_id) {
log::error!("Cannot construct: invalid channel id {}.", channel_id);
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
Ok(channel_id)
}
@@ -306,7 +306,7 @@ impl<R: Role> Header<R> {
let channel_id = Self::validate_channel(channel_id)?;
if channel_id == BROADCAST_CHANNEL_ID {
log::error!("Cannot construct: illegal broadcast.");
- return Err(Error::UnexpectedInput);
+ return Err(Error::unexpected_input());
}
Ok(channel_id)
}
Why this scored 14/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.