Skip to content

Commit e69a507

Browse files
Merge pull request SixLabors#2824 from SixLabors/js/backport-2780
Backport : V3 Fix SixLabors#2779 buffer overrun
2 parents 4584377 + 911480d commit e69a507

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

src/ImageSharp/Image.WrapMemory.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
5050
{
5151
Guard.NotNull(configuration, nameof(configuration));
5252
Guard.NotNull(metadata, nameof(metadata));
53-
Guard.IsTrue(pixelMemory.Length >= width * height, nameof(pixelMemory), "The length of the input memory is less than the specified image size");
53+
Guard.IsTrue(pixelMemory.Length >= (long)width * height, nameof(pixelMemory), "The length of the input memory is less than the specified image size");
5454

5555
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(pixelMemory);
5656
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
@@ -145,7 +145,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
145145
{
146146
Guard.NotNull(configuration, nameof(configuration));
147147
Guard.NotNull(metadata, nameof(metadata));
148-
Guard.IsTrue(pixelMemoryOwner.Memory.Length >= width * height, nameof(pixelMemoryOwner), "The length of the input memory is less than the specified image size");
148+
Guard.IsTrue(pixelMemoryOwner.Memory.Length >= (long)width * height, nameof(pixelMemoryOwner), "The length of the input memory is less than the specified image size");
149149

150150
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(pixelMemoryOwner);
151151
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
@@ -232,7 +232,7 @@ public static Image<TPixel> WrapMemory<TPixel>(
232232

233233
ByteMemoryManager<TPixel> memoryManager = new(byteMemory);
234234

235-
Guard.IsTrue(memoryManager.Memory.Length >= width * height, nameof(byteMemory), "The length of the input memory is less than the specified image size");
235+
Guard.IsTrue(memoryManager.Memory.Length >= (long)width * height, nameof(byteMemory), "The length of the input memory is less than the specified image size");
236236

237237
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory);
238238
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
@@ -422,10 +422,11 @@ public static unsafe Image<TPixel> WrapMemory<TPixel>(
422422
Guard.IsFalse(pointer == null, nameof(pointer), "Pointer must be not null");
423423
Guard.NotNull(configuration, nameof(configuration));
424424
Guard.NotNull(metadata, nameof(metadata));
425+
Guard.MustBeLessThanOrEqualTo(height * (long)width, int.MaxValue, "Total amount of pixels exceeds int.MaxValue");
425426

426427
UnmanagedMemoryManager<TPixel> memoryManager = new(pointer, width * height);
427428

428-
Guard.MustBeGreaterThanOrEqualTo(bufferSizeInBytes, memoryManager.Memory.Span.Length, nameof(bufferSizeInBytes));
429+
Guard.MustBeGreaterThanOrEqualTo(bufferSizeInBytes / sizeof(TPixel), memoryManager.Memory.Span.Length, nameof(bufferSizeInBytes));
429430

430431
MemoryGroup<TPixel> memorySource = MemoryGroup<TPixel>.Wrap(memoryManager.Memory);
431432
return new Image<TPixel>(configuration, memorySource, width, height, metadata);

tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,11 @@ public void WrapSystemDrawingBitmap_FromBytes_WhenObserved()
294294
}
295295
}
296296

297-
[Fact]
298-
public unsafe void WrapMemory_Throws_OnTooLessWrongSize()
297+
[Theory]
298+
[InlineData(20, 5, 5)]
299+
[InlineData(1023, 32, 32)]
300+
[InlineData(65536, 65537, 65536)]
301+
public unsafe void WrapMemory_Throws_OnTooLessWrongSize(int size, int width, int height)
299302
{
300303
var cfg = Configuration.CreateDefaultInstance();
301304
var metaData = new ImageMetadata();
@@ -306,7 +309,7 @@ public unsafe void WrapMemory_Throws_OnTooLessWrongSize()
306309
{
307310
try
308311
{
309-
using var image = Image.WrapMemory<Rgba32>(cfg, ptr, 24, 5, 5, metaData);
312+
using var image = Image.WrapMemory<Rgba32>(cfg, ptr, size * sizeof(Rgba32), width, height, metaData);
310313
}
311314
catch (Exception e)
312315
{
@@ -317,24 +320,30 @@ public unsafe void WrapMemory_Throws_OnTooLessWrongSize()
317320
Assert.IsType<ArgumentOutOfRangeException>(thrownException);
318321
}
319322

320-
[Fact]
321-
public unsafe void WrapMemory_FromPointer_CreatedImageIsCorrect()
323+
[Theory]
324+
[InlineData(25, 5, 5)]
325+
[InlineData(26, 5, 5)]
326+
[InlineData(2, 1, 1)]
327+
[InlineData(1024, 32, 32)]
328+
[InlineData(2048, 32, 32)]
329+
public unsafe void WrapMemory_FromPointer_CreatedImageIsCorrect(int size, int width, int height)
322330
{
323331
var cfg = Configuration.CreateDefaultInstance();
324332
var metaData = new ImageMetadata();
325333

326-
var array = new Rgba32[25];
334+
var array = new Rgba32[size];
327335

328336
fixed (void* ptr = array)
329337
{
330-
using (var image = Image.WrapMemory<Rgba32>(cfg, ptr, 25, 5, 5, metaData))
338+
using (var image = Image.WrapMemory<Rgba32>(cfg, ptr, size * sizeof(Rgba32), width, height, metaData))
331339
{
332340
Assert.True(image.DangerousTryGetSinglePixelMemory(out Memory<Rgba32> imageMem));
333341
Span<Rgba32> imageSpan = imageMem.Span;
342+
Span<Rgba32> sourceSpan = array.AsSpan(0, width * height);
334343
ref Rgba32 pixel0 = ref imageSpan[0];
335-
Assert.True(Unsafe.AreSame(ref array[0], ref pixel0));
344+
Assert.True(Unsafe.AreSame(ref sourceSpan[0], ref pixel0));
336345
ref Rgba32 pixel_1 = ref imageSpan[imageSpan.Length - 1];
337-
Assert.True(Unsafe.AreSame(ref array[array.Length - 1], ref pixel_1));
346+
Assert.True(Unsafe.AreSame(ref sourceSpan[sourceSpan.Length - 1], ref pixel_1));
338347

339348
Assert.Equal(cfg, image.Configuration);
340349
Assert.Equal(metaData, image.Metadata);
@@ -395,6 +404,7 @@ public unsafe void WrapSystemDrawingBitmap_FromPointer()
395404
[InlineData(0, 5, 5)]
396405
[InlineData(20, 5, 5)]
397406
[InlineData(1023, 32, 32)]
407+
[InlineData(65536, 65537, 65536)]
398408
public void WrapMemory_MemoryOfT_InvalidSize(int size, int height, int width)
399409
{
400410
var array = new Rgba32[size];
@@ -430,6 +440,7 @@ private class TestMemoryOwner<T> : IMemoryOwner<T>
430440
[InlineData(0, 5, 5)]
431441
[InlineData(20, 5, 5)]
432442
[InlineData(1023, 32, 32)]
443+
[InlineData(65536, 65537, 65536)]
433444
public void WrapMemory_IMemoryOwnerOfT_InvalidSize(int size, int height, int width)
434445
{
435446
var array = new Rgba32[size];
@@ -476,6 +487,7 @@ public void WrapMemory_IMemoryOwnerOfT_ValidSize(int size, int height, int width
476487
[InlineData(0, 5, 5)]
477488
[InlineData(20, 5, 5)]
478489
[InlineData(1023, 32, 32)]
490+
[InlineData(65536, 65537, 65536)]
479491
public void WrapMemory_IMemoryOwnerOfByte_InvalidSize(int size, int height, int width)
480492
{
481493
var array = new byte[size * Unsafe.SizeOf<Rgba32>()];

0 commit comments

Comments
 (0)