Browse Source

Guard CgBI bit depth and color type

pull/3137/head
Erik White 2 months ago
parent
commit
29ae5f8409
  1. 16
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  2. 22
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  3. 4
      tests/ImageSharp.Tests/TestImages.cs
  4. 3
      tests/Images/Input/Png/cgbi/colors-cgbi-bitdepth16.png
  5. 3
      tests/Images/Input/Png/cgbi/colors-cgbi-palette.png

16
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -1431,6 +1431,22 @@ internal sealed class PngDecoderCore : ImageDecoderCore
this.pngColorType = this.header.ColorType;
this.Dimensions = new Size(this.header.Width, this.header.Height);
// Apple's pngcrush emits the CgBI chunk before IHDR, so the header
// compatibility check is deferred until both chunks have been seen.
if (this.isCgbi)
{
ThrowIfInvalidCgbiContent(this.header);
}
}
private static void ThrowIfInvalidCgbiContent(in PngHeader header)
{
if (header.BitDepth != 8 || (header.ColorType is not PngColorType.Rgb and not PngColorType.RgbWithAlpha))
{
PngThrowHelper.ThrowInvalidImageContentException(
$"CgBI is only supported for 8-bit truecolor images. Was bit depth '{header.BitDepth}', color type '{header.ColorType}'.");
}
}
/// <summary>

22
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -767,6 +767,28 @@ public partial class PngDecoderTests
Assert.Equal(expectedHeight, imageInfo.Height);
}
[Theory]
[InlineData(TestImages.Png.Cgbi.BitDepth16)]
[InlineData(TestImages.Png.Cgbi.Palette)]
public void Identify_CgBI_IncompatibleHeader_ThrowsInvalidImageContentException(string imagePath)
{
TestFile testFile = TestFile.Create(imagePath);
using MemoryStream stream = new(testFile.Bytes, false);
InvalidImageContentException ex = Assert.Throws<InvalidImageContentException>(() => Image.Identify(stream));
Assert.Contains("CgBI is only supported for 8-bit truecolor images", ex.Message);
}
[Theory]
[WithFile(TestImages.Png.Cgbi.BitDepth16, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Cgbi.Palette, PixelTypes.Rgba32)]
public void Decode_CgBI_IncompatibleHeader_ThrowsInvalidImageContentException<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
InvalidImageContentException ex = Assert.Throws<InvalidImageContentException>(
() => { using Image<TPixel> image = provider.GetImage(PngDecoder.Instance); });
Assert.Contains("CgBI is only supported for 8-bit truecolor images", ex.Message);
}
[Theory]
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)]

4
tests/ImageSharp.Tests/TestImages.cs

@ -189,6 +189,10 @@ public static class TestImages
// Issue 410: https://github.com/SixLabors/ImageSharp/issues/410
public const string Issue410 = "Png/issues/Issue_410.png";
// Synthetic fixtures derived from colors.png to exercise CgBI validation.
public const string BitDepth16 = "Png/cgbi/colors-cgbi-bitdepth16.png";
public const string Palette = "Png/cgbi/colors-cgbi-palette.png";
}
public static class Bad

3
tests/Images/Input/Png/cgbi/colors-cgbi-bitdepth16.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:59610bc03f6ca867e5f71c574b3a0d1942c9e3a230c8a32bf3007cb82f286866
size 12853

3
tests/Images/Input/Png/cgbi/colors-cgbi-palette.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a3a2f20c69ae423523a8f41887e3f37257a338f2220c2ea44d35c87daf8c3aa3
size 12853
Loading…
Cancel
Save