diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs index 4cd4b4aac9..4e2315cd88 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs @@ -224,6 +224,13 @@ internal abstract class BaseExifReader this.Seek(offset); ulong count = this.ReadUInt64(); + // Each entry occupies 20 bytes and the directory ends with an 8-byte next-IFD offset. + long remainingDirectoryBytes = this.data.Length - this.data.Position; + if (remainingDirectoryBytes < 8 || count > (ulong)((remainingDirectoryBytes - 8) / 20)) + { + throw new InvalidImageContentException("The BigTIFF directory entry count exceeds the available data."); + } + Span offsetBuffer = stackalloc byte[8]; for (ulong i = 0; i < count; i++) { diff --git a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs index 72f53cab78..769ee00a82 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffDecoderTests.cs @@ -115,4 +115,17 @@ public class BigTiffDecoderTests : TiffDecoderBaseTester Assert.Equal(1, meta.Values.Count(v => (ushort)v.Tag == (ushort)ExifTagValue.StripOffsets)); Assert.Equal(1, meta.Values.Count(v => (ushort)v.Tag == (ushort)ExifTagValue.StripByteCounts)); } + + [Fact] + public void TiffDecoder_DirectoryEntryCountExceedsAvailableData_Throws() + { + byte[] data = + [ + 0x49, 0x49, 0x2B, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF2, 0x05, 0x2A, 0x01, 0x00, 0x00, 0x00, + ]; + + Assert.Throws(() => Image.Load(data)); + } }