Skip to content

Commit a1f2879

Browse files
Merge pull request #2756 from SixLabors/af/git-av-2.1
Backport GIF LZW fix to 2.1
2 parents 7ce329a + 898df7f commit a1f2879

File tree

14 files changed

+67
-11
lines changed

14 files changed

+67
-11
lines changed

src/ImageSharp/Formats/Gif/LzwDecoder.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ internal sealed class LzwDecoder : IDisposable
2020
/// </summary>
2121
private const int MaxStackSize = 4096;
2222

23+
/// <summary>
24+
/// The maximum bits for a lzw code.
25+
/// </summary>
26+
private const int MaximumLzwBits = 12;
27+
2328
/// <summary>
2429
/// The null code.
2530
/// </summary>
@@ -74,12 +79,12 @@ public void DecodePixels(int minCodeSize, Buffer2D<byte> pixels)
7479
// It is possible to specify a larger LZW minimum code size than the palette length in bits
7580
// which may leave a gap in the codes where no colors are assigned.
7681
// http://www.matthewflickinger.com/lab/whatsinagif/lzw_image_data.asp#lzw_compression
77-
if (minCodeSize < 2 || clearCode > MaxStackSize)
82+
if (minCodeSize < 2 || minCodeSize > MaximumLzwBits || clearCode > MaxStackSize)
7883
{
7984
// Don't attempt to decode the frame indices.
8085
// Theoretically we could determine a min code size from the length of the provided
8186
// color palette but we won't bother since the image is most likely corrupted.
82-
GifThrowHelper.ThrowInvalidImageContentException("Gif Image does not contain a valid LZW minimum code.");
87+
return;
8388
}
8489

8590
// The resulting index table length.

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

+14-9
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,9 @@ public void Issue2012EmptyXmp<TPixel>(TestImageProvider<TPixel> provider)
279279
public void Issue2012BadMinCode<TPixel>(TestImageProvider<TPixel> provider)
280280
where TPixel : unmanaged, IPixel<TPixel>
281281
{
282-
Exception ex = Record.Exception(
283-
() =>
284-
{
285-
using Image<TPixel> image = provider.GetImage();
286-
image.DebugSave(provider);
287-
});
288-
289-
Assert.NotNull(ex);
290-
Assert.Contains("Gif Image does not contain a valid LZW minimum code.", ex.Message);
282+
using Image<TPixel> image = provider.GetImage();
283+
image.DebugSave(provider);
284+
image.CompareToReferenceOutput(provider);
291285
}
292286

293287
// https://bugzilla.mozilla.org/show_bug.cgi?id=55918
@@ -301,5 +295,16 @@ public void IssueDeferredClearCode<TPixel>(TestImageProvider<TPixel> provider)
301295
image.DebugSave(provider);
302296
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
303297
}
298+
299+
// https://github.com/SixLabors/ImageSharp/issues/2743
300+
[Theory]
301+
[WithFile(TestImages.Gif.Issues.BadMaxLzwBits, PixelTypes.Rgba32)]
302+
public void IssueTooLargeLzwBits<TPixel>(TestImageProvider<TPixel> provider)
303+
where TPixel : unmanaged, IPixel<TPixel>
304+
{
305+
using Image<TPixel> image = provider.GetImage();
306+
image.DebugSaveMultiFrame(provider);
307+
image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
308+
}
304309
}
305310
}

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

+15
Original file line numberDiff line numberDiff line change
@@ -190,5 +190,20 @@ public void Decode_VerifyRepeatCount(string imagePath, uint repeatCount)
190190
}
191191
}
192192
}
193+
194+
[Theory]
195+
[InlineData(TestImages.Gif.Issues.BadMaxLzwBits, 8)]
196+
[InlineData(TestImages.Gif.Issues.Issue2012BadMinCode, 1)]
197+
public void Identify_Frames_Bad_Lzw(string imagePath, int framesCount)
198+
{
199+
TestFile testFile = TestFile.Create(imagePath);
200+
using MemoryStream stream = new(testFile.Bytes, false);
201+
202+
IImageInfo imageInfo = Image.Identify(stream);
203+
204+
Assert.NotNull(imageInfo);
205+
GifMetadata gifMetadata = imageInfo.Metadata.GetGifMetadata();
206+
Assert.NotNull(gifMetadata);
207+
}
193208
}
194209
}

tests/ImageSharp.Tests/TestImages.cs

+1
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ public static class Issues
455455
public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif";
456456
public const string BadAppExtLength_2 = "Gif/issues/issue405_badappextlength252-2.gif";
457457
public const string BadDescriptorWidth = "Gif/issues/issue403_baddescriptorwidth.gif";
458+
public const string BadMaxLzwBits = "Gif/issues/issue_2743.gif";
458459
public const string DeferredClearCode = "Gif/issues/bugzilla-55918.gif";
459460
public const string Issue1505 = "Gif/issues/issue1505_argumentoutofrange.png";
460461
public const string Issue1530 = "Gif/issues/issue1530.gif";
Loading

0 commit comments

Comments
 (0)