Skip to content

Commit 8762bde

Browse files
Add tests and fix for handling invalid input.
1 parent eb11973 commit 8762bde

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
2222

2323
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
2424
{
25-
short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(header);
26-
return header.Length >= this.HeaderSize &&
27-
(fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray);
25+
if (header.Length >= this.HeaderSize)
26+
{
27+
short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(header);
28+
return fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray;
29+
}
30+
31+
return false;
2832
}
2933
}
3034
}

src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
2323
{
2424
if (header.Length >= this.HeaderSize)
2525
{
26-
// There is no magick bytes in a tga file, so at least the image type
26+
// There are no magic bytes in a tga file, so at least the image type
2727
// and the colormap type in the header will be checked for a valid value.
2828
if (header[1] != 0 && header[1] != 1)
2929
{
@@ -34,7 +34,7 @@ private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
3434
return imageType.IsValid();
3535
}
3636

37-
return true;
37+
return false;
3838
}
3939
}
4040
}

src/ImageSharp/Image.Decode.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.IO;
56
using System.Linq;
67
using SixLabors.ImageSharp.Formats;
@@ -47,19 +48,26 @@ internal static Image<TPixel> CreateUninitialized<TPixel>(
4748
/// <returns>The mime type or null if none found.</returns>
4849
private static IImageFormat InternalDetectFormat(Stream stream, Configuration config)
4950
{
50-
// This is probably a candidate for making into a public API in the future!
51-
int maxHeaderSize = config.MaxHeaderSize;
52-
if (maxHeaderSize <= 0)
51+
// We take a minimum of the stream length vs the max header size and always check below
52+
// to ensure that only formats that headers fit within the given buffer length are tested.
53+
int headerSize = (int)Math.Min(config.MaxHeaderSize, stream.Length);
54+
if (headerSize <= 0)
5355
{
5456
return null;
5557
}
5658

57-
using (IManagedByteBuffer buffer = config.MemoryAllocator.AllocateManagedByteBuffer(maxHeaderSize, AllocationOptions.Clean))
59+
using (IManagedByteBuffer buffer = config.MemoryAllocator.AllocateManagedByteBuffer(headerSize, AllocationOptions.Clean))
5860
{
5961
long startPosition = stream.Position;
60-
stream.Read(buffer.Array, 0, maxHeaderSize);
62+
stream.Read(buffer.Array, 0, headerSize);
6163
stream.Position = startPosition;
62-
return config.ImageFormatsManager.FormatDetectors.Select(x => x.DetectFormat(buffer.GetSpan())).LastOrDefault(x => x != null);
64+
65+
// Does the given stream contain enough data to fit in the header for the format
66+
// and does that data match the format specification?
67+
// Individual formats should still check since they are public.
68+
return config.ImageFormatsManager.FormatDetectors
69+
.Where(x => x.HeaderSize <= headerSize)
70+
.Select(x => x.DetectFormat(buffer.GetSpan())).LastOrDefault(x => x != null);
6371
}
6472
}
6573

tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,20 @@ public void CanIdentifyImageLoadedFromBytes(int width, int height, string extens
191191
}
192192
}
193193

194+
[Fact]
195+
public void IdentifyReturnsNullWithInvalidStream()
196+
{
197+
byte[] invalid = new byte[10];
198+
199+
using (var memoryStream = new MemoryStream(invalid))
200+
{
201+
IImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format);
202+
203+
Assert.Null(imageInfo);
204+
Assert.Null(format);
205+
}
206+
}
207+
194208
private static IImageFormat GetFormat(string format)
195209
{
196210
return Configuration.Default.ImageFormats.FirstOrDefault(x => x.FileExtensions.Contains(format));

0 commit comments

Comments
 (0)