Browse Source

Merge pull request #1892 from SixLabors/bp/fix1897

Tiff: Add maximum IFD threshold
pull/1893/head
Brian Popow 5 years ago
committed by GitHub
parent
commit
2c27919473
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      src/ImageSharp/Formats/Tiff/Ifd/DirectoryReader.cs
  2. 2
      src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs
  3. 12
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  4. 1
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Tiff/Issues/Issue1891.tiff

12
src/ImageSharp/Formats/Tiff/Ifd/DirectoryReader.cs

@ -18,9 +18,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
private uint nextIfdOffset;
private const int DirectoryMax = 65534;
// used for sequential read big values (actual for multiframe big files)
// todo: different tags can link to the same data (stream offset) - investigate
private readonly SortedList<uint, Action> lazyLoaders = new SortedList<uint, Action>(new DuplicateKeyComparer<uint>());
private readonly SortedList<uint, Action> lazyLoaders = new(new DuplicateKeyComparer<uint>());
public DirectoryReader(Stream stream) => this.stream = stream;
@ -48,7 +50,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
return ByteOrder.LittleEndian;
}
else if (headerBytes[0] == TiffConstants.ByteOrderBigEndian && headerBytes[1] == TiffConstants.ByteOrderBigEndian)
if (headerBytes[0] == TiffConstants.ByteOrderBigEndian && headerBytes[1] == TiffConstants.ByteOrderBigEndian)
{
return ByteOrder.BigEndian;
}
@ -67,6 +70,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
this.nextIfdOffset = reader.NextIfdOffset;
readers.Add(reader);
if (readers.Count >= DirectoryMax)
{
TiffThrowHelper.ThrowImageFormatException("TIFF image contains too many directories");
}
}
// Sequential reading big values.

2
src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs

@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
this.lazyLoaders = lazyLoaders;
}
public List<IExifValue> Values { get; } = new List<IExifValue>();
public List<IExifValue> Values { get; } = new();
public uint NextIfdOffset { get; private set; }

12
tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs

@ -380,6 +380,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
public void TiffDecoder_CanDecode_JpegCompressed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider, useExactComparer: false);
// https://github.com/SixLabors/ImageSharp/issues/1891
[Theory]
[WithFile(Issues1891, PixelTypes.Rgba32)]
public void TiffDecoder_ThrowsException_WithTooManyDirectories<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => Assert.Throws<ImageFormatException>(
() =>
{
using (provider.GetImage(TiffDecoder))
{
}
});
[Theory]
[WithFileCollection(nameof(MultiframeTestImages), PixelTypes.Rgba32)]
public void DecodeMultiframe<TPixel>(TestImageProvider<TPixel> provider)

1
tests/ImageSharp.Tests/TestImages.cs

@ -840,6 +840,7 @@ namespace SixLabors.ImageSharp.Tests
public const string Flower32BitGrayPredictorLittleEndian = "Tiff/flower-minisblack-32_lsb_deflate_predictor.tiff";
public const string Issues1716Rgb161616BitLittleEndian = "Tiff/Issues/Issue1716.tiff";
public const string Issues1891 = "Tiff/Issues/Issue1891.tiff";
public const string SmallRgbDeflate = "Tiff/rgb_small_deflate.tiff";
public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff";

3
tests/Images/Input/Tiff/Issues/Issue1891.tiff

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