diff --git a/embedded-service/src/hid/command.rs b/embedded-service/src/hid/command.rs index 30bb9599..c0c5f5d1 100644 --- a/embedded-service/src/hid/command.rs +++ b/embedded-service/src/hid/command.rs @@ -310,21 +310,25 @@ impl<'a> Command<'a> { Opcode::Reset => Command::Reset, Opcode::GetReport => { if report_type? == ReportType::Input || report_type? == ReportType::Feature { - Command::GetReport(report_type?, report_id.unwrap()) + Command::GetReport(report_type?, report_id.ok_or(Error::RequiresReportId)?) } else { return Err(Error::InvalidReportType); } } Opcode::SetReport => { if report_type? == ReportType::Output || report_type? == ReportType::Feature { - Command::SetReport(report_type?, report_id.unwrap(), data.unwrap()) + Command::SetReport( + report_type?, + report_id.ok_or(Error::RequiresReportId)?, + data.ok_or(Error::RequiresData)?, + ) } else { return Err(Error::InvalidReportType); } } - Opcode::GetIdle => Command::GetIdle(report_id.unwrap()), + Opcode::GetIdle => Command::GetIdle(report_id.ok_or(Error::RequiresReportId)?), Opcode::SetIdle => Command::SetIdle( - report_id.unwrap(), + report_id.ok_or(Error::RequiresReportId)?, cmd.try_into().map_err(|_| Error::InvalidReportFreq)?, ), Opcode::GetProtocol => Command::GetProtocol, @@ -338,6 +342,8 @@ impl<'a> Command<'a> { /// Encodes common values for a command with a report ID into a slice /// Returns the number of bytes written and the remaining buffer + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] fn encode_common( buf: &mut [u8], opcode: Opcode, @@ -381,6 +387,8 @@ impl<'a> Command<'a> { /// Encodes an operation with no report ID or additional data into a slice /// Returns the number of bytes written and the remaining buffer + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] fn encode_basic_op(buf: &mut [u8], opcode: Opcode) -> Result<(usize, &mut [u8]), Error> { if buf.len() < BASIC_CMD_LEN { return Err(Error::InvalidSize(InvalidSizeError { @@ -395,6 +403,8 @@ impl<'a> Command<'a> { /// Encodes a register address into a slice /// Returns the number of bytes written and the remaining buffer + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] fn encode_register(buf: &mut [u8], reg: Option) -> Result<(usize, &mut [u8]), Error> { if let Some(reg) = reg { if buf.len() < REGISTER_LEN { @@ -412,6 +422,8 @@ impl<'a> Command<'a> { /// Encodes a u16 value into a slice, prefixed by a length /// Returns the number of bytes written and the remaining buffer + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] fn encode_value>(buf: &mut [u8], value: T) -> Result<(usize, &mut [u8]), Error> { if buf.len() < LENGTH_VALUE_LEN { return Err(Error::InvalidSize(InvalidSizeError { @@ -427,6 +439,8 @@ impl<'a> Command<'a> { /// Encodes data into a slice, prefixed by a length /// Returns the number of bytes written and the remaining buffer + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] fn encode_data<'b>(buf: &'b mut [u8], data: &[u8]) -> Result<(usize, &'b mut [u8]), Error> { // +2 to encode the length of the data let total_len = data.len() + 2; @@ -528,7 +542,13 @@ impl<'a> Command<'a> { Command::SetPower(state) => { let opcode: u16 = Opcode::SetPower.into(); let state: u16 = (*state).into(); - buf[0..2].copy_from_slice(&(opcode | state).to_le_bytes()); + let buf_len = buf.len(); + buf.get_mut(0..2) + .ok_or(Error::InvalidSize(InvalidSizeError { + expected: 2, + actual: buf_len, + }))? + .copy_from_slice(&(opcode | state).to_le_bytes()); len += 2; } Command::Vendor => { diff --git a/embedded-service/src/hid/mod.rs b/embedded-service/src/hid/mod.rs index 941ebbe8..892531fc 100644 --- a/embedded-service/src/hid/mod.rs +++ b/embedded-service/src/hid/mod.rs @@ -76,6 +76,8 @@ pub struct Descriptor { impl Descriptor { /// Serializes a descriptor into the slice + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] pub fn encode_into_slice(&self, buf: &mut [u8]) -> Result { if buf.len() < DESCRIPTOR_LEN { return Err(Error::InvalidSize(InvalidSizeError { @@ -104,6 +106,8 @@ impl Descriptor { } /// Deserializes a descriptor from the slice + // panic safety: we check the length at the start of the function + #[allow(clippy::indexing_slicing)] pub fn decode_from_slice(buf: &[u8]) -> Result { if buf.len() < DESCRIPTOR_LEN { return Err(Error::InvalidSize(InvalidSizeError {