diff --git a/CHANGELOG.md b/CHANGELOG.md index 880c8cf73a..e5bb9b2252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Bottom level categories: - BREAKING: Migrated from the `maxInterStageShaderComponents` limit to `maxInterStageShaderVariables`, which changes validation in a way that should not affect most programs. This follows the latest changes of the WebGPU spec. By @ErichDonGubler in [#8652](https://github.com/gfx-rs/wgpu/pull/8652). - Fixed validation of the texture format in GPUDepthStencilState when neither depth nor stencil is actually enabled. By @andyleiserson in [#8766](https://github.com/gfx-rs/wgpu/pull/8766). +- Don't crash in the `Display` implementation of `CreateTextureViewError::TooMany{MipLevels,ArrayLayers}` when their base and offset overflow. By @ErichDonGubler in [8808](https://github.com/gfx-rs/wgpu/pull/8808). #### GLES diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index d8fae8f370..9d402ba6a0 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1800,9 +1800,9 @@ pub enum CreateTextureViewError { #[error("Array layer count is 0")] ZeroArrayLayerCount, #[error( - "TextureView spans mip levels [{base_mip_level}, {end_mip_level}) \ - (mipLevelCount {mip_level_count}) but the texture view only has {total} total mip levels", - end_mip_level = base_mip_level + mip_level_count + "`TextureView` spans mip levels [{base_mip_level}, {end_mip_level}) \ + (`mipLevelCount` is {mip_level_count}) but the texture view only has {total} total mip level(s))", + end_mip_level = BasePlusOffset(*base_mip_level, *mip_level_count) )] TooManyMipLevels { base_mip_level: u32, @@ -1810,9 +1810,9 @@ pub enum CreateTextureViewError { total: u32, }, #[error( - "TextureView spans array layers [{base_array_layer}, {end_array_layer}) \ - (arrayLayerCount {array_layer_count}) but the texture view only has {total} total layers", - end_array_layer = base_array_layer + array_layer_count + "`TextureView` spans array layers [{base_array_layer}, {end_array_layer}) \ + (`arrayLayerCount` is {array_layer_count}) but the texture view only has {total} total layer(s))", + end_array_layer = BasePlusOffset(*base_array_layer, *array_layer_count) )] TooManyArrayLayers { base_array_layer: u32, @@ -1872,6 +1872,20 @@ impl WebGpuError for CreateTextureViewError { } } +/// Diagnostic structure for [`Display`](fmt::Display)'ing a base + offset calculation, accounting +/// for overflow. +struct BasePlusOffset(u32, u32); + +impl fmt::Display for BasePlusOffset { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let &Self(base, offset) = self; + match base.checked_add(offset) { + Some(sum) => fmt::Display::fmt(&sum, f), + None => write!(f, ""), + } + } +} + #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum TextureViewDestroyError {}