Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
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
24 changes: 20 additions & 4 deletions src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ internal struct BmpInfoHeader
/// </summary>
public const int HeaderSizeSize = 4;

/// <summary>
/// Maximum dimensions of a bitmap with or height: 2**31 - 1, since width and height are int32
/// </summary>
private const int MaximumBmpDimension = 2147483647;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not being used?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it's no longer used, it's now removed.


/// <summary>
/// Maximum size of a bitmap width * height: 2**32, since size is uint32.
/// </summary>
private const long MaximumBmpSize = 4294967296;

public BmpInfoHeader(
int headerSize,
int width,
Expand Down Expand Up @@ -545,13 +555,19 @@ public void WriteV5Header(Span<byte> buffer)

internal void VerifyDimensions()
{
const int MaximumBmpDimension = 65535;

if (this.Width > MaximumBmpDimension || this.Height > MaximumBmpDimension)
{
throw new InvalidOperationException(
$"The input bmp '{this.Width}x{this.Height}' is "
+ $"bigger then the max allowed size '{MaximumBmpDimension}x{MaximumBmpDimension}'");
$"The input bmp '{this.Width}x{this.Height}' has a width or height "
+ $"bigger then the max allowed '{MaximumBmpDimension}'");
}

long size = this.Width * this.Height;
if (size > MaximumBmpSize)
{
throw new InvalidOperationException(
$"The input bmp '{this.Width}x{this.Height}' has a size {size}"
+ $"bigger then the max allowed '{MaximumBmpSize}'");
}
}
}
Expand Down
26 changes: 20 additions & 6 deletions tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System;
using System.IO;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Bmp;
Expand All @@ -20,6 +21,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp
[Trait("Format", "Bmp")]
public class BmpEncoderTests
{
private static BmpEncoder BmpEncoder => new();

public static readonly TheoryData<BmpBitsPerPixel> BitsPerPixel =
new()
{
Expand Down Expand Up @@ -50,14 +53,12 @@ public class BmpEncoderTests
[MemberData(nameof(RatioFiles))]
public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var options = new BmpEncoder();

var testFile = TestFile.Create(imagePath);
using (Image<Rgba32> input = testFile.CreateRgba32Image())
{
using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
input.Save(memStream, BmpEncoder);

memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
Expand All @@ -75,14 +76,12 @@ public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolut
[MemberData(nameof(BmpBitsPerPixelFiles))]
public void Encode_PreserveBitsPerPixel(string imagePath, BmpBitsPerPixel bmpBitsPerPixel)
{
var options = new BmpEncoder();

var testFile = TestFile.Create(imagePath);
using (Image<Rgba32> input = testFile.CreateRgba32Image())
{
using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
input.Save(memStream, BmpEncoder);

memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
Expand Down Expand Up @@ -328,6 +327,21 @@ public void Encode_PreservesColorProfile<TPixel>(TestImageProvider<TPixel> provi
}
}

[Theory]
[InlineData(1, 66535)]
[InlineData(66535, 1)]
public void Encode_WorksWithSizeGreaterThen65k(int width, int height)
{
Exception exception = Record.Exception(() =>
{
using Image image = new Image<Rgba32>(width, height);
using var memStream = new MemoryStream();
image.Save(memStream, BmpEncoder);
});

Assert.Null(exception);
}

[Theory]
[WithFile(Car, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)]
[WithFile(V5Header, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)]
Expand Down