Skip to content

Commit 0bc6d4f

Browse files
Merge pull request #29 from embedded-rust-iml/fix/out-of-bounds-write
Check for buffer overflow in prerendered variant
2 parents 4e0e1c3 + 9346ba1 commit 0bc6d4f

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

src/prerendered.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ pub const MODE: Mode = Mode {
2323
phase: Phase::CaptureOnFirstTransition,
2424
};
2525

26+
#[derive(Debug)]
27+
pub enum Error<E> {
28+
OutOfBounds,
29+
Spi(E),
30+
}
31+
2632
pub mod devices {
2733
pub struct Ws2812;
2834
pub struct Sk6812w;
@@ -92,17 +98,22 @@ where
9298
SPI: FullDuplex<u8, Error = E>,
9399
{
94100
/// Write a single byte for ws2812 devices
95-
fn write_byte(&mut self, mut data: u8) {
101+
fn write_byte(&mut self, mut data: u8) -> Result<(), Error<E>> {
96102
// Send two bits in one spi byte. High time first, then the low time
97103
// The maximum for T0H is 500ns, the minimum for one bit 1063 ns.
98104
// These result in the upper and lower spi frequency limits
99105
let patterns = [0b1000_1000, 0b1000_1110, 0b11101000, 0b11101110];
106+
107+
if self.index > self.data.len() - 4 {
108+
return Err(Error::OutOfBounds);
109+
}
100110
for _ in 0..4 {
101111
let bits = (data & 0b1100_0000) >> 6;
102112
self.data[self.index] = patterns[bits as usize];
103113
self.index += 1;
104114
data <<= 2;
105115
}
116+
Ok(())
106117
}
107118

108119
fn send_data(&mut self) -> Result<(), E> {
@@ -134,10 +145,10 @@ impl<'a, SPI, E> SmartLedsWrite for Ws2812<'a, SPI>
134145
where
135146
SPI: FullDuplex<u8, Error = E>,
136147
{
137-
type Error = E;
148+
type Error = Error<E>;
138149
type Color = RGB8;
139150
/// Write all the items of an iterator to a ws2812 strip
140-
fn write<T, I>(&mut self, iterator: T) -> Result<(), E>
151+
fn write<T, I>(&mut self, iterator: T) -> Result<(), Error<E>>
141152
where
142153
T: Iterator<Item = I>,
143154
I: Into<Self::Color>,
@@ -146,22 +157,22 @@ where
146157

147158
for item in iterator {
148159
let item = item.into();
149-
self.write_byte(item.g);
150-
self.write_byte(item.r);
151-
self.write_byte(item.b);
160+
self.write_byte(item.g)?;
161+
self.write_byte(item.r)?;
162+
self.write_byte(item.b)?;
152163
}
153-
self.send_data()
164+
self.send_data().map_err(|e| Error::Spi(e))
154165
}
155166
}
156167

157168
impl<'a, SPI, E> SmartLedsWrite for Ws2812<'a, SPI, devices::Sk6812w>
158169
where
159170
SPI: FullDuplex<u8, Error = E>,
160171
{
161-
type Error = E;
172+
type Error = Error<E>;
162173
type Color = RGBW<u8, u8>;
163174
/// Write all the items of an iterator to a ws2812 strip
164-
fn write<T, I>(&mut self, iterator: T) -> Result<(), E>
175+
fn write<T, I>(&mut self, iterator: T) -> Result<(), Error<E>>
165176
where
166177
T: Iterator<Item = I>,
167178
I: Into<Self::Color>,
@@ -170,11 +181,11 @@ where
170181

171182
for item in iterator {
172183
let item = item.into();
173-
self.write_byte(item.g);
174-
self.write_byte(item.r);
175-
self.write_byte(item.b);
176-
self.write_byte(item.a.0);
184+
self.write_byte(item.g)?;
185+
self.write_byte(item.r)?;
186+
self.write_byte(item.b)?;
187+
self.write_byte(item.a.0)?;
177188
}
178-
self.send_data()
189+
self.send_data().map_err(|e| Error::Spi(e))
179190
}
180191
}

0 commit comments

Comments
 (0)