Skip to content

Commit 7704ec1

Browse files
committed
Audit panics and add clippy lints
1 parent dcc4d71 commit 7704ec1

File tree

6 files changed

+66
-29
lines changed

6 files changed

+66
-29
lines changed

Cargo.toml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "tps6699x"
33
version = "0.1.0"
44
edition = "2021"
55
license = "MIT"
6-
rust-version = "1.83"
6+
rust-version = "1.88"
77

88
[dependencies]
99
bitfield = "0.19.0"
@@ -40,3 +40,17 @@ critical-section = { version = "1.1", features = ["std"] }
4040
embedded-hal-mock = { version = "0.11.1", features = ["embedded-hal-async"] }
4141
tokio = { version = "1.42.0", features = ["rt", "macros", "time"] }
4242
static_cell = "2.1.0"
43+
44+
[lints.clippy]
45+
correctness = "deny"
46+
expect_used = "deny"
47+
indexing_slicing = "deny"
48+
panic = "deny"
49+
panic_in_result_fn = "deny"
50+
perf = "deny"
51+
suspicious = "deny"
52+
style = "deny"
53+
todo = "deny"
54+
unimplemented = "deny"
55+
unreachable = "deny"
56+
unwrap_used = "deny"

src/asynchronous/embassy/fw_update.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ impl<M: RawMutex, B: I2c> UpdateTarget for Tps6699x<'_, M, B> {
1919
with_timeout(Command::Tfus.timeout(), inner.execute_tfus(delay)).await
2020
};
2121

22-
if result.is_err() {
22+
if let Ok(result) = result {
23+
result
24+
} else {
2325
error!("Enter FW mode timeout");
24-
return PdError::Timeout.into();
26+
PdError::Timeout.into()
2527
}
26-
27-
result.unwrap()
2828
}
2929

3030
/// Initialize the firmware update with the TFUi command
@@ -93,7 +93,10 @@ impl<M: RawMutex, B: I2c> UpdateTarget for Tps6699x<'_, M, B> {
9393
bincode::decode_from_slice(&return_bytes, config::standard().with_fixed_int_encoding())
9494
.map_err(|_| PdError::Serialize)?;
9595

96-
Ok(ret.block_status[block_index])
96+
ret.block_status
97+
.get(block_index)
98+
.cloned()
99+
.ok_or(Error::Pd(PdError::InvalidParams))
97100
}
98101

99102
async fn fw_update_stream_data(
@@ -126,12 +129,12 @@ impl<M: RawMutex, B: I2c> UpdateTarget for Tps6699x<'_, M, B> {
126129
with_timeout(Command::Tfuc.timeout(), inner.execute_tfuc(delay)).await
127130
};
128131

129-
if result.is_err() {
132+
if let Ok(result) = result {
133+
result
134+
} else {
130135
error!("Complete timeout");
131-
return PdError::Timeout.into();
136+
PdError::Timeout.into()
132137
}
133-
134-
result.unwrap()
135138
}
136139

137140
async fn fw_update_burst_write(&mut self, address: u8, data: &[u8]) -> Result<(), Error<Self::BusError>> {

src/asynchronous/embassy/mod.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,21 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
273273
}
274274

275275
if done {
276-
// Put back any unhandled interrupt flags for future processing
276+
// Panic safety: `unhandled`, `accumulated_flags`, and `mask` are all of size MAX_SUPPORTED_PORTS
277+
// so this will never index out of bounds
278+
#[allow(clippy::indexing_slicing)]
277279
let unhandled = from_fn(|i| accumulated_flags[i] & !mask[i]);
280+
281+
// Put back any unhandled interrupt flags for future processing
278282
if unhandled.iter().any(|&f| f != IntEventBus1::new_zero()) {
279283
// If there are unhandled flags, signal them for future processing
280284
trace!("Signaling unhandled interrupt flags: {:?}", unhandled);
281285
self.controller.interrupt_waker.signal(unhandled);
282286
}
287+
288+
// Panic safety: the return type, `accumulated_flags`, and `mask` are all of size MAX_SUPPORTED_PORTS
289+
// so this will never index out of bounds
290+
#[allow(clippy::indexing_slicing)]
283291
return from_fn(|i| accumulated_flags[i] & mask[i]);
284292
}
285293
}
@@ -329,18 +337,18 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
329337
) -> Result<ReturnValue, Error<B::Error>> {
330338
let timeout = cmd.timeout();
331339
let result = with_timeout(timeout, self.execute_command_no_timeout(port, cmd, indata, outdata)).await;
332-
if result.is_err() {
340+
if let Ok(result) = result {
341+
result
342+
} else {
333343
error!("Command {:#?} timed out", cmd);
334344
// See if there's a definite error we can read
335345
let mut inner = self.lock_inner().await;
336-
return match inner.read_command_result(port, None, cmd.has_return_value()).await? {
346+
match inner.read_command_result(port, None, cmd.has_return_value()).await? {
337347
ReturnValue::Rejected => PdError::Rejected,
338348
_ => PdError::Timeout,
339349
}
340-
.into();
350+
.into()
341351
}
342-
343-
result.unwrap()
344352
}
345353

346354
async fn execute_srdy(&mut self, port: LocalPortId, switch: SrdySwitch) -> Result<ReturnValue, Error<B::Error>> {
@@ -390,7 +398,8 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
390398
let args = trig::Args { edge, cmd };
391399
let mut args_buf = [0; trig::ARGS_LEN];
392400

393-
bincode::encode_into_slice(args, &mut args_buf, config::standard().with_fixed_int_encoding()).unwrap();
401+
bincode::encode_into_slice(args, &mut args_buf, config::standard().with_fixed_int_encoding())
402+
.map_err(|_| Error::Pd(PdError::InvalidParams))?;
394403

395404
self.execute_command(port, Command::Trig, Some(&args_buf), None).await
396405
}
@@ -639,10 +648,9 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
639648
.get_rx_caps(port, register, &mut out_spr_pdos, &mut out_epr_pdos)
640649
.await?;
641650

642-
// These unwraps are safe because we know the sizes of the arrays
643651
Ok(rx_caps::RxCaps {
644-
spr: heapless::Vec::from_slice(&out_spr_pdos[..num_valid_spr]).unwrap(),
645-
epr: heapless::Vec::from_slice(&out_epr_pdos[..num_valid_epr]).unwrap(),
652+
spr: heapless::Vec::from_iter(out_spr_pdos.into_iter().take(num_valid_spr)),
653+
epr: heapless::Vec::from_iter(out_epr_pdos.into_iter().take(num_valid_epr)),
646654
})
647655
}
648656

@@ -807,10 +815,19 @@ impl<'a, M: RawMutex, B: I2c> Interrupt<'a, M, B> {
807815
{
808816
let interrupts_enabled = self.controller.interrupts_enabled();
809817
let mut inner = self.lock_inner().await;
810-
for port in 0..inner.num_ports() {
818+
819+
// Note: `interrupts_enabled` and `flags` are both of size MAX_SUPPORTED_PORTS and so
820+
// will always have a 1:1 mapping. If `num_ports` ever returns a value larger than
821+
// MAX_SUPPORTED_PORTS, `port` will simply be capped at MAX_SUPPORTED_PORTS.
822+
for (port, (interrupt_enabled, flag)) in interrupts_enabled
823+
.iter()
824+
.zip(flags.iter_mut())
825+
.take(inner.num_ports())
826+
.enumerate()
827+
{
811828
let port_id = LocalPortId(port as u8);
812829

813-
if !interrupts_enabled[port] {
830+
if !interrupt_enabled {
814831
trace!("{:?}: Interrupt for disabled", port_id);
815832
continue;
816833
}
@@ -830,7 +847,7 @@ impl<'a, M: RawMutex, B: I2c> Interrupt<'a, M, B> {
830847

831848
match with_timeout(Duration::from_millis(100), inner.clear_interrupt(port_id)).await {
832849
Ok(res) => match res {
833-
Ok(event) => flags[port] |= event,
850+
Ok(event) => *flag |= event,
834851
Err(_e) => {
835852
continue;
836853
}

src/asynchronous/embassy/rx_caps.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@ impl<T: Common> RxCaps<T> {
7171
impl From<RxCaps<source::Pdo>> for RxCaps<pdo::Pdo> {
7272
fn from(value: RxCaps<source::Pdo>) -> Self {
7373
RxCaps {
74-
spr: value.spr_as_slice().iter().map(|pdo| pdo.clone().into()).collect(),
75-
epr: value.epr_as_slice().iter().map(|pdo| pdo.clone().into()).collect(),
74+
spr: value.spr_as_slice().iter().map(|&pdo| pdo.into()).collect(),
75+
epr: value.epr_as_slice().iter().map(|&pdo| pdo.into()).collect(),
7676
}
7777
}
7878
}
7979

8080
impl From<RxCaps<sink::Pdo>> for RxCaps<pdo::Pdo> {
8181
fn from(value: RxCaps<sink::Pdo>) -> Self {
8282
RxCaps {
83-
spr: value.spr_as_slice().iter().map(|pdo| pdo.clone().into()).collect(),
84-
epr: value.epr_as_slice().iter().map(|pdo| pdo.clone().into()).collect(),
83+
spr: value.spr_as_slice().iter().map(|&pdo| pdo.into()).collect(),
84+
epr: value.epr_as_slice().iter().map(|&pdo| pdo.into()).collect(),
8585
}
8686
}
8787
}

src/asynchronous/embassy/ucsi.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
5858

5959
// First byte returned is number of bytes written, we don't use it so erase it
6060
outdata.rotate_left(1);
61-
outdata.last_mut().map(|b| *b = 0);
61+
if let Some(b) = outdata.last_mut() {
62+
*b = 0;
63+
}
6264
}
6365

6466
Ok(ReturnValue::Success)
@@ -74,7 +76,7 @@ impl<'a, M: RawMutex, B: I2c> Tps6699x<'a, M, B> {
7476
let port = command.port();
7577

7678
// Internally the controller uses 1-based port numbering
77-
let mut command = command.clone();
79+
let mut command = *command;
7880
command.set_port(LocalPortId(command.port().0 + 1));
7981

8082
encode_into_slice(

src/registers/autonegotiate_sink.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ impl From<u8> for PpsRequestInterval {
163163
0x2 => PpsRequestInterval::TwoSeconds,
164164
0x3 => PpsRequestInterval::OneSecond,
165165
// Panic safety: All possible u8 values are unit tested
166+
#[allow(clippy::unreachable)]
166167
_ => unreachable!(),
167168
}
168169
}

0 commit comments

Comments
 (0)