From f59e1eed24b0bff3619e0e8536b8e35d468858e9 Mon Sep 17 00:00:00 2001 From: Chris Doble Date: Fri, 28 Nov 2025 11:41:28 +1100 Subject: Fix a bug where CDC ACM BufferedReceiver repeats data when its future is dropped --- embassy-usb/CHANGELOG.md | 1 + embassy-usb/src/class/cdc_acm.rs | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/embassy-usb/CHANGELOG.md b/embassy-usb/CHANGELOG.md index 3dd71ffbc..f90875166 100644 --- a/embassy-usb/CHANGELOG.md +++ b/embassy-usb/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support for USB HID Boot Protocol Mode - Bump usbd-hid from 0.8.1 to 0.9.0 +- Fix a bug where CDC ACM BufferedReceiver repeats data when its future is dropped ## 0.5.1 - 2025-08-26 diff --git a/embassy-usb/src/class/cdc_acm.rs b/embassy-usb/src/class/cdc_acm.rs index 388e21fbd..c990b679e 100644 --- a/embassy-usb/src/class/cdc_acm.rs +++ b/embassy-usb/src/class/cdc_acm.rs @@ -545,9 +545,12 @@ impl<'d, D: Driver<'d>> embedded_io_async::Read for BufferedReceiver<'d, D> { return self.receiver.read_packet(buf).await; } - // Otherwise read a packet into the internal buffer, and return some of it to the caller - self.start = 0; + // Otherwise read a packet into the internal buffer, and return some of it to the caller. + // + // It's important that `start` and `end` be updated in this order so they're left in a + // consistent state if the `read` future is dropped mid-execution, e.g. from a timeout. self.end = self.receiver.read_packet(&mut self.buffer).await?; + self.start = 0; return Ok(self.read_from_buffer(buf)); } } -- cgit