Browse Source

Reject undersized ICC tag entries

pull/3187/head
James Jackson-South 4 weeks ago
parent
commit
73d8e02077
  1. 3
      src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs
  2. 23
      tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs

3
src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs

@ -119,6 +119,7 @@ internal sealed class IccReader
} }
List<IccTagTableEntry> table = new((int)tagCount); List<IccTagTableEntry> table = new((int)tagCount);
uint dataLength = (uint)reader.DataLength;
for (int i = 0; i < tagCount; i++) for (int i = 0; i < tagCount; i++)
{ {
uint tagSignature = reader.ReadUInt32(); uint tagSignature = reader.ReadUInt32();
@ -126,7 +127,7 @@ internal sealed class IccReader
uint tagSize = reader.ReadUInt32(); uint tagSize = reader.ReadUInt32();
// Exclude entries that have nonsense values and could cause exceptions further on // Exclude entries that have nonsense values and could cause exceptions further on
if (tagOffset < reader.DataLength && tagSize < reader.DataLength - 128) if (tagSize >= 8 && tagOffset <= dataLength && tagSize <= dataLength - tagOffset)
{ {
table.Add(new IccTagTableEntry((IccProfileTag)tagSignature, tagOffset, tagSize)); table.Add(new IccTagTableEntry((IccProfileTag)tagSignature, tagOffset, tagSize));
} }

23
tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Buffers.Binary;
using SixLabors.ImageSharp.Metadata.Profiles.Icc; using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestDataIcc; using SixLabors.ImageSharp.Tests.TestDataIcc;
@ -59,4 +60,26 @@ public class IccReaderTests
Assert.Equal(header.Size, expected.Size); Assert.Equal(header.Size, expected.Size);
Assert.Equal(header.Version, expected.Version); Assert.Equal(header.Version, expected.Version);
} }
[Fact]
public void ReadProfile_WithUndersizedArrayTags_IgnoresTags()
{
const int tagCount = 100;
const int dataOffset = 132 + (tagCount * 12);
byte[] data = new byte[dataOffset + 16];
BinaryPrimitives.WriteUInt32BigEndian(data.AsSpan(128), tagCount);
for (int i = 0; i < tagCount; i++)
{
Span<byte> entry = data.AsSpan(132 + (i * 12), 12);
BinaryPrimitives.WriteUInt32BigEndian(entry, 0x73663332);
BinaryPrimitives.WriteUInt32BigEndian(entry[4..], dataOffset);
BinaryPrimitives.WriteUInt32BigEndian(entry[8..], 0);
}
BinaryPrimitives.WriteUInt32BigEndian(data.AsSpan(dataOffset), 0x73663332);
IccProfile profile = new(data);
Assert.Empty(profile.Entries);
}
} }

Loading…
Cancel
Save