Skip to content

Commit 4387db9

Browse files
committed
Limit lzw bits to a maximum of 12 bits, fixes issue #2743
1 parent 467850f commit 4387db9

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

src/ImageSharp/Formats/Gif/LzwDecoder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ internal sealed class LzwDecoder : IDisposable
1919
/// </summary>
2020
private const int MaxStackSize = 4096;
2121

22+
/// <summary>
23+
/// The maximum bits for a lzw code.
24+
/// </summary>
25+
private const int MaximumLzwBits = 12;
26+
2227
/// <summary>
2328
/// The null code.
2429
/// </summary>
@@ -73,7 +78,7 @@ public void DecodePixels(int minCodeSize, Buffer2D<byte> pixels)
7378
// It is possible to specify a larger LZW minimum code size than the palette length in bits
7479
// which may leave a gap in the codes where no colors are assigned.
7580
// http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
76-
if (minCodeSize < 2 || clearCode > MaxStackSize)
81+
if (minCodeSize < 2 || minCodeSize > MaximumLzwBits || clearCode > MaxStackSize)
7782
{
7883
// Don't attempt to decode the frame indices.
7984
// Theoretically we could determine a min code size from the length of the provided
@@ -245,7 +250,7 @@ public void SkipIndices(int minCodeSize, int length)
245250
// It is possible to specify a larger LZW minimum code size than the palette length in bits
246251
// which may leave a gap in the codes where no colors are assigned.
247252
// http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
248-
if (minCodeSize < 2 || clearCode > MaxStackSize)
253+
if (minCodeSize < 2 || minCodeSize > MaximumLzwBits || clearCode > MaxStackSize)
249254
{
250255
// Don't attempt to decode the frame indices.
251256
// Theoretically we could determine a min code size from the length of the provided

tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,21 @@ public void IssueDeferredClearCode<TPixel>(TestImageProvider<TPixel> provider)
318318
image.DebugSave(provider);
319319
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
320320
}
321+
322+
// https://github.com/SixLabors/ImageSharp/issues/2743
323+
[Theory]
324+
[WithFile(TestImages.Gif.Issues.BadMaxLzwBits, PixelTypes.Rgba32)]
325+
public void IssueTooLargeLzwBits<TPixel>(TestImageProvider<TPixel> provider)
326+
where TPixel : unmanaged, IPixel<TPixel>
327+
{
328+
Exception ex = Record.Exception(
329+
() =>
330+
{
331+
using Image<TPixel> image = provider.GetImage();
332+
image.DebugSave(provider);
333+
});
334+
335+
Assert.NotNull(ex);
336+
Assert.Contains("Gif Image does not contain a valid LZW minimum code.", ex.Message);
337+
}
321338
}

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ public static class Issues
516516
public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif";
517517
public const string BadAppExtLength_2 = "Gif/issues/issue405_badappextlength252-2.gif";
518518
public const string BadDescriptorWidth = "Gif/issues/issue403_baddescriptorwidth.gif";
519+
public const string BadMaxLzwBits = "Gif/issues/issue_2743.gif";
519520
public const string DeferredClearCode = "Gif/issues/bugzilla-55918.gif";
520521
public const string Issue1505 = "Gif/issues/issue1505_argumentoutofrange.png";
521522
public const string Issue1530 = "Gif/issues/issue1530.gif";
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)