diff --git a/src/actions/splash.rs b/src/actions/splash.rs index 6e1ca91..991aecf 100644 --- a/src/actions/splash.rs +++ b/src/actions/splash.rs @@ -120,7 +120,8 @@ fn draw(image: DynamicImage) -> Result<()> { let image = resize_to_fit(&image, fit); // Create a framebuffer to draw the image on. - let mut framebuffer = Framebuffer::new(width, height); + let mut framebuffer = + Framebuffer::new(width, height).context("unable to create framebuffer")?; // Iterate over the pixels in the image and put them on the framebuffer. for (x, y, pixel) in image.enumerate_pixels() { diff --git a/src/utils/framebuffer.rs b/src/utils/framebuffer.rs index 7fcf55a..6b3afc4 100644 --- a/src/utils/framebuffer.rs +++ b/src/utils/framebuffer.rs @@ -13,17 +13,28 @@ pub struct Framebuffer { impl Framebuffer { /// Creates a new framebuffer of the specified `width` and `height`. - pub fn new(width: usize, height: usize) -> Self { - Framebuffer { + pub fn new(width: usize, height: usize) -> Result { + // Verify that the size is valid during multiplication. + let size = width + .checked_mul(height) + .context("framebuffer size overflow")?; + + // Initialize the pixel buffer with black pixels, with the verified size. + let pixels = vec![BltPixel::new(0, 0, 0); size]; + + Ok(Framebuffer { width, height, - pixels: vec![BltPixel::new(0, 0, 0); width * height], - } + pixels, + }) } /// Mutably acquires a pixel of the framebuffer at the specified `x` and `y` coordinate. pub fn pixel(&mut self, x: usize, y: usize) -> Option<&mut BltPixel> { - self.pixels.get_mut(y * self.width + x) + // Calculate the index of the pixel safely, returning None if it overflows. + let index = y.checked_mul(self.width)?.checked_add(x)?; + // Return the pixel at the index. If the index is out of bounds, this will return None. + self.pixels.get_mut(index) } /// Blit the framebuffer to the specified `gop` [GraphicsOutput].