From 2fbad7d845e325a456b896a773235f2a13a7841f Mon Sep 17 00:00:00 2001 From: andriyDev Date: Fri, 22 Nov 2024 10:14:53 -0800 Subject: [PATCH] Fix off-by-one error on `Image::get_color_at` and `Image::set_color_at`. (#16475) # Objective - Fixes #16474. ## Solution - Check that the pixel x,y,z is less than width,height,depth. - Classic off-by-one. ## Testing - Added a test. --- crates/bevy_image/src/image.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/crates/bevy_image/src/image.rs b/crates/bevy_image/src/image.rs index cfe3a768d6..63ea5c8f1a 100644 --- a/crates/bevy_image/src/image.rs +++ b/crates/bevy_image/src/image.rs @@ -944,19 +944,19 @@ impl Image { let pixel_size = self.texture_descriptor.format.pixel_size(); let pixel_offset = match self.texture_descriptor.dimension { TextureDimension::D3 => { - if coords.x > width || coords.y > height || coords.z > depth { + if coords.x >= width || coords.y >= height || coords.z >= depth { return None; } coords.z * height * width + coords.y * width + coords.x } TextureDimension::D2 => { - if coords.x > width || coords.y > height { + if coords.x >= width || coords.y >= height { return None; } coords.y * width + coords.x } TextureDimension::D1 => { - if coords.x > width { + if coords.x >= width { return None; } coords.x @@ -1573,4 +1573,28 @@ mod test { assert_eq!(UVec2::ONE, image.size()); assert_eq!(Vec2::ONE, image.size_f32()); } + + #[test] + fn on_edge_pixel_is_invalid() { + let image = Image::new_fill( + Extent3d { + width: 5, + height: 10, + depth_or_array_layers: 1, + }, + TextureDimension::D2, + &[0, 0, 0, 255], + TextureFormat::Rgba8Unorm, + RenderAssetUsages::MAIN_WORLD, + ); + assert!(matches!(image.get_color_at(4, 9), Ok(Color::BLACK))); + assert!(matches!( + image.get_color_at(0, 10), + Err(TextureAccessError::OutOfBounds { x: 0, y: 10, z: 0 }) + )); + assert!(matches!( + image.get_color_at(5, 10), + Err(TextureAccessError::OutOfBounds { x: 5, y: 10, z: 0 }) + )); + } }