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.
This commit is contained in:
andriyDev 2024-11-22 10:14:53 -08:00 committed by GitHub
parent b1e4512648
commit 2fbad7d845
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -944,19 +944,19 @@ impl Image {
let pixel_size = self.texture_descriptor.format.pixel_size(); let pixel_size = self.texture_descriptor.format.pixel_size();
let pixel_offset = match self.texture_descriptor.dimension { let pixel_offset = match self.texture_descriptor.dimension {
TextureDimension::D3 => { TextureDimension::D3 => {
if coords.x > width || coords.y > height || coords.z > depth { if coords.x >= width || coords.y >= height || coords.z >= depth {
return None; return None;
} }
coords.z * height * width + coords.y * width + coords.x coords.z * height * width + coords.y * width + coords.x
} }
TextureDimension::D2 => { TextureDimension::D2 => {
if coords.x > width || coords.y > height { if coords.x >= width || coords.y >= height {
return None; return None;
} }
coords.y * width + coords.x coords.y * width + coords.x
} }
TextureDimension::D1 => { TextureDimension::D1 => {
if coords.x > width { if coords.x >= width {
return None; return None;
} }
coords.x coords.x
@ -1573,4 +1573,28 @@ mod test {
assert_eq!(UVec2::ONE, image.size()); assert_eq!(UVec2::ONE, image.size());
assert_eq!(Vec2::ONE, image.size_f32()); 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 })
));
}
} }