From 347279c2585cf5c44e19f4cd1ac287110742d8e2 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 17 Jun 2021 19:10:28 +0200 Subject: [PATCH] Clamp color map index, fixes issue #1668 --- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 7 ++++--- .../Formats/Gif/GifDecoderTests.cs | 14 ++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 1 + ...lorIndex_Rgba32_issue1668_invalidcolorindex.png | 3 +++ .../Gif/issues/issue1668_invalidcolorindex.gif | 3 +++ 5 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1668_InvalidColorIndex_Rgba32_issue1668_invalidcolorindex.png create mode 100644 tests/Images/Input/Gif/issues/issue1668_invalidcolorindex.gif diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index 2f6b45aff..fb3d989d4 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -7,7 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Threading.Tasks; + using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; @@ -441,6 +441,7 @@ namespace SixLabors.ImageSharp.Formats.Gif int descriptorRight = descriptorLeft + descriptor.Width; bool transFlag = this.graphicsControlExtension.TransparencyFlag; byte transIndex = this.graphicsControlExtension.TransparencyIndex; + int colorTableMaxIdx = colorTable.Length - 1; for (int y = descriptorTop; y < descriptorBottom && y < imageHeight; y++) { @@ -487,7 +488,7 @@ namespace SixLabors.ImageSharp.Formats.Gif // #403 The left + width value can be larger than the image width for (int x = descriptorLeft; x < descriptorRight && x < imageWidth; x++) { - int index = Unsafe.Add(ref indicesRowRef, x - descriptorLeft); + int index = Numerics.Clamp(Unsafe.Add(ref indicesRowRef, x - descriptorLeft), 0, colorTableMaxIdx); ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); Rgb24 rgb = colorTable[index]; pixel.FromRgb24(rgb); @@ -497,7 +498,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { for (int x = descriptorLeft; x < descriptorRight && x < imageWidth; x++) { - int index = Unsafe.Add(ref indicesRowRef, x - descriptorLeft); + int index = Numerics.Clamp(Unsafe.Add(ref indicesRowRef, x - descriptorLeft), 0, colorTableMaxIdx); if (transIndex != index) { ref TPixel pixel = ref Unsafe.Add(ref rowRef, x); diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index 446f1e9d4..c3250d72c 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -197,6 +197,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif } } + // https://github.com/SixLabors/ImageSharp/issues/1668 + [Theory] + [WithFile(TestImages.Gif.Issues.InvalidColorIndex, PixelTypes.Rgba32)] + public void Issue1668_InvalidColorIndex(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage()) + { + image.DebugSave(provider); + + image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider); + } + } + [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] [WithFile(TestImages.Gif.Kumin, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 7eca4795d..6d2f65f57 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -418,6 +418,7 @@ namespace SixLabors.ImageSharp.Tests public const string BadDescriptorWidth = "Gif/issues/issue403_baddescriptorwidth.gif"; public const string Issue1505 = "Gif/issues/issue1505_argumentoutofrange.png"; public const string Issue1530 = "Gif/issues/issue1530.gif"; + public const string InvalidColorIndex = "Gif/issues/issue1668_invalidcolorindex.gif"; } public static readonly string[] All = { Rings, Giphy, Cheers, Trans, Kumin, Leo, Ratio4x1, Ratio1x4 }; diff --git a/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1668_InvalidColorIndex_Rgba32_issue1668_invalidcolorindex.png b/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1668_InvalidColorIndex_Rgba32_issue1668_invalidcolorindex.png new file mode 100644 index 000000000..fc713e385 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1668_InvalidColorIndex_Rgba32_issue1668_invalidcolorindex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8507b2f70c1dd2ef3d3ef616419825cf70c7453abaf7fd490349f85f4b589cb5 +size 408 diff --git a/tests/Images/Input/Gif/issues/issue1668_invalidcolorindex.gif b/tests/Images/Input/Gif/issues/issue1668_invalidcolorindex.gif new file mode 100644 index 000000000..6847817fa --- /dev/null +++ b/tests/Images/Input/Gif/issues/issue1668_invalidcolorindex.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:712d53330f8774ec4ec73fe8321641e2a457ec4bdef813352940dfc93c83c789 +size 3256