From 860e48b0f0ec51c8596bc12985a8b37bad4fba00 Mon Sep 17 00:00:00 2001 From: Josh McKinney Date: Tue, 22 Oct 2024 03:46:27 -0700 Subject: [PATCH] fix(buffer): buffer::get_pos() now correctly handles index > u16::MAX (#1447) Previously this function wrapped the index pass u16::MAX which caused problems rendering. Fixes: --- src/buffer/buffer.rs | 32 +++++++++++++++++++++++++++----- src/style/color.rs | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/buffer/buffer.rs b/src/buffer/buffer.rs index 8bc77e9a..dc73aeb3 100644 --- a/src/buffer/buffer.rs +++ b/src/buffer/buffer.rs @@ -303,15 +303,17 @@ impl Buffer { /// buffer.pos_of(100); // Panics /// ``` #[must_use] - pub fn pos_of(&self, i: usize) -> (u16, u16) { + pub fn pos_of(&self, index: usize) -> (u16, u16) { debug_assert!( - i < self.content.len(), - "Trying to get the coords of a cell outside the buffer: i={i} len={}", + index < self.content.len(), + "Trying to get the coords of a cell outside the buffer: i={index} len={}", self.content.len() ); + let x = index % self.area.width as usize + self.area.x as usize; + let y = index / self.area.width as usize + self.area.y as usize; ( - self.area.x + (i as u16) % self.area.width, - self.area.y + (i as u16) / self.area.width, + u16::try_from(x).expect("x overflow. This should never happen as area.width is u16"), + u16::try_from(y).expect("y overflow. This should never happen as area.height is u16"), ) } @@ -1274,4 +1276,24 @@ mod tests { let expected = Buffer::with_lines([expected]); assert_eq!(buffer, expected); } + + /// Regression test for + /// + /// Previously the `pos_of` function would incorrectly cast the index to a u16 value instead of + /// using the index as is. This caused incorrect rendering of any buffer with an length > 65535. + #[test] + fn index_pos_of_u16_max() { + let buffer = Buffer::empty(Rect::new(0, 0, 256, 256 + 1)); + assert_eq!(buffer.index_of(255, 255), 65535); + assert_eq!(buffer.pos_of(65535), (255, 255)); + + assert_eq!(buffer.index_of(0, 256), 65536); + assert_eq!(buffer.pos_of(65536), (0, 256)); // previously (0, 0) + + assert_eq!(buffer.index_of(1, 256), 65537); + assert_eq!(buffer.pos_of(65537), (1, 256)); // previously (1, 0) + + assert_eq!(buffer.index_of(255, 256), 65791); + assert_eq!(buffer.pos_of(65791), (255, 256)); // previously (255, 0) + } } diff --git a/src/style/color.rs b/src/style/color.rs index 4826f60b..1c0b61f1 100644 --- a/src/style/color.rs +++ b/src/style/color.rs @@ -480,6 +480,7 @@ mod tests { #[cfg(feature = "palette")] use palette::{Hsl, Hsluv}; + #[cfg(feature = "palette")] use rstest::rstest; #[cfg(feature = "serde")] use serde::de::{Deserialize, IntoDeserializer};