From 6eaacde1055f19a4a6c89032490001d88b00f7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20R=C3=B3=C5=BCycki?= Date: Mon, 9 Dec 2024 22:33:55 +0100 Subject: [PATCH] Fix bugs in frame.rs --- src/frame.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/frame.rs b/src/frame.rs index 64ce02c..2da5769 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -29,8 +29,15 @@ where peek(cons, 0) .zip(peek(cons, 1)) .map(|(l1, l2)| u16::from_le_bytes([*l1, *l2])) - .map(|l| l as usize) - .filter(|len| *len < cons.len()) + .map(|l| { + // If we seem to have received a frame which length is not divisible + // by 3, the only guaranteed way to recover is to panic and restart. + assert!(l % 3 == 0); + l as usize + }) + // Only return Some if cons contains the full frame: at least len bytes + // for subpixel values, plus 2 bytes for the length itself. + .filter(|len| *len + 2 <= cons.len()) } pub async fn display_frame(cons: &mut Consumer, len: usize, ws2812: &mut Ws2812<'_, P, S>) @@ -39,7 +46,10 @@ where R::Rb: RbRead, P: Instance, { - for (r, g, b) in cons.pop_iter().skip(2).take(len).tuples() { + // Pop the first two bytes containing the length + cons.skip(2); + + for (r, g, b) in cons.pop_iter().take(len).tuples() { ws2812.write(r, g, b); } // wait for the state machine to write all bytes