Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add tests and fix for handling invalid input.
  • Loading branch information
JimBobSquarePants committed Dec 4, 2019
commit 8762bdeccebdcc35e369d88641e415ef16af6c66
10 changes: 7 additions & 3 deletions src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ public IImageFormat DetectFormat(ReadOnlySpan<byte> header)

private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
{
short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(header);
return header.Length >= this.HeaderSize &&
(fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray);
if (header.Length >= this.HeaderSize)
{
short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(header);
return fileTypeMarker == BmpConstants.TypeMarkers.Bitmap || fileTypeMarker == BmpConstants.TypeMarkers.BitmapArray;
}

return false;
}
}
}
4 changes: 2 additions & 2 deletions src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
{
if (header.Length >= this.HeaderSize)
{
// There is no magick bytes in a tga file, so at least the image type
// There are no magic bytes in a tga file, so at least the image type
// and the colormap type in the header will be checked for a valid value.
if (header[1] != 0 && header[1] != 1)
{
Expand All @@ -34,7 +34,7 @@ private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
return imageType.IsValid();
}

return true;
return false;
}
}
}
20 changes: 14 additions & 6 deletions src/ImageSharp/Image.Decode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

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

using (IManagedByteBuffer buffer = config.MemoryAllocator.AllocateManagedByteBuffer(maxHeaderSize, AllocationOptions.Clean))
using (IManagedByteBuffer buffer = config.MemoryAllocator.AllocateManagedByteBuffer(headerSize, AllocationOptions.Clean))
{
long startPosition = stream.Position;
stream.Read(buffer.Array, 0, maxHeaderSize);
stream.Read(buffer.Array, 0, headerSize);
stream.Position = startPosition;
return config.ImageFormatsManager.FormatDetectors.Select(x => x.DetectFormat(buffer.GetSpan())).LastOrDefault(x => x != null);

// Does the given stream contain enough data to fit in the header for the format
// and does that data match the format specification?
// Individual formats should still check since they are public.
return config.ImageFormatsManager.FormatDetectors
.Where(x => x.HeaderSize <= headerSize)
.Select(x => x.DetectFormat(buffer.GetSpan())).LastOrDefault(x => x != null);
}
}

Expand Down
14 changes: 14 additions & 0 deletions tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,20 @@ public void CanIdentifyImageLoadedFromBytes(int width, int height, string extens
}
}

[Fact]
public void IdentifyReturnsNullWithInvalidStream()
{
byte[] invalid = new byte[10];

using (var memoryStream = new MemoryStream(invalid))
{
IImageInfo imageInfo = Image.Identify(memoryStream, out IImageFormat format);

Assert.Null(imageInfo);
Assert.Null(format);
}
}

private static IImageFormat GetFormat(string format)
{
return Configuration.Default.ImageFormats.FirstOrDefault(x => x.FileExtensions.Contains(format));
Expand Down