message: Add validation for DX10 header
diff: @@ -28,6 +28,13 @@ enum DecoderError {
  /// Wrong DDS header flags
  HeaderFlagsInvalid(u32),
  + /// Invalid DXGI format in DX10 header
  + DxgiFormatInvalid(u32),
  + /// Invalid flags in DX10 header
  + Dx10FlagsInvalid(u32),
  + /// Invalid array size in DX10 header
  + Dx10ArraySizeInvalid(u32),
  +
  /// DDS "DDS " signature invalid or missing
  DdsSignatureInvalid,
  }
  @@ -171,13 +178,43 @@ impl DX10Header {
  let array_size = r.read_u32::<LittleEndian>()?;
  let misc_flags_2 = r.read_u32::<LittleEndian>()?;
  - Ok(Self {
  + let dx10_header = Self {
  dxgi_format,
  resource_dimension,
  misc_flag,
  array_size,
  misc_flags_2,
  - })
  + };
  + dx10_header.validate()?;
  +
  + Ok(dx10_header)
  + }
  +
  + fn validate(&self) -> Result<(), ImageError> {
  + // Note: see https://docs.microsoft.com/en-us/windows/win32/direct3ddds/dds-header-dxt10 for info on valid values
  + if dxgi_format < 0 || dxgi_format > 132 {
  + // Invalid format
  + return Err(DecoderError::DxgiFormatInvalid(dxgi_format).into());
  + }
  +
  + if misc_flag != 0x4 && misc_flag != 0x4 {
  + // Invalid flag
  + // Only no (0x0) and DDS_RESOURCE_MISC_TEXTURECUBE (0x4) flags are allowed
  + return Err(DecoderError::Dx10FlagsInvalid(misc_flag).into());
  + }
  +
  + if resource_dimension == 4 && array_size != 1 {
  + // Invalid array size
  + // 3D textures (resource dimension == 4) must have an array size of 1
  + return Err(DecoderError::Dx10ArraySizeInvalid(array_size).into());
  + }
  +
  + if misc_flags_2 < 0x0 || misc_flags_2 > 0x4 {
  + // Invalid alpha flags
  + return Err(DecoderError::Dx10FlagsInvalid(misc_flags_2).into());
  + }
  +
  + Ok(())
  }
  }
  