Skip to content

Commit

Permalink
Limit lzw bits to a maximum of 12 bits, fixes issue #2743
Browse files Browse the repository at this point in the history
  • Loading branch information
brianpopow committed May 31, 2024
1 parent 467850f commit 4387db9
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/ImageSharp/Formats/Gif/LzwDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ internal sealed class LzwDecoder : IDisposable
/// </summary>
private const int MaxStackSize = 4096;

/// <summary>
/// The maximum bits for a lzw code.
/// </summary>
private const int MaximumLzwBits = 12;

/// <summary>
/// The null code.
/// </summary>
Expand Down Expand Up @@ -73,7 +78,7 @@ public void DecodePixels(int minCodeSize, Buffer2D<byte> pixels)
// It is possible to specify a larger LZW minimum code size than the palette length in bits
// which may leave a gap in the codes where no colors are assigned.
// http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
if (minCodeSize < 2 || clearCode > MaxStackSize)
if (minCodeSize < 2 || minCodeSize > MaximumLzwBits || clearCode > MaxStackSize)
{
// Don't attempt to decode the frame indices.
// Theoretically we could determine a min code size from the length of the provided
Expand Down Expand Up @@ -245,7 +250,7 @@ public void SkipIndices(int minCodeSize, int length)
// It is possible to specify a larger LZW minimum code size than the palette length in bits
// which may leave a gap in the codes where no colors are assigned.
// http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
if (minCodeSize < 2 || clearCode > MaxStackSize)
if (minCodeSize < 2 || minCodeSize > MaximumLzwBits || clearCode > MaxStackSize)
{
// Don't attempt to decode the frame indices.
// Theoretically we could determine a min code size from the length of the provided
Expand Down
17 changes: 17 additions & 0 deletions tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,4 +318,21 @@ public void IssueDeferredClearCode<TPixel>(TestImageProvider<TPixel> provider)
image.DebugSave(provider);
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
}

// https://github.com/SixLabors/ImageSharp/issues/2743
[Theory]
[WithFile(TestImages.Gif.Issues.BadMaxLzwBits, PixelTypes.Rgba32)]
public void IssueTooLargeLzwBits<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
Exception ex = Record.Exception(
() =>
{
using Image<TPixel> image = provider.GetImage();
image.DebugSave(provider);
});

Assert.NotNull(ex);
Assert.Contains("Gif Image does not contain a valid LZW minimum code.", ex.Message);
}
}
1 change: 1 addition & 0 deletions tests/ImageSharp.Tests/TestImages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ public static class Issues
public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif";
public const string BadAppExtLength_2 = "Gif/issues/issue405_badappextlength252-2.gif";
public const string BadDescriptorWidth = "Gif/issues/issue403_baddescriptorwidth.gif";
public const string BadMaxLzwBits = "Gif/issues/issue_2743.gif";
public const string DeferredClearCode = "Gif/issues/bugzilla-55918.gif";
public const string Issue1505 = "Gif/issues/issue1505_argumentoutofrange.png";
public const string Issue1530 = "Gif/issues/issue1530.gif";
Expand Down
3 changes: 3 additions & 0 deletions tests/Images/Input/Gif/issues/issue_2743.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4387db9

Please sign in to comment.