diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index a336c9c591..8249f8136c 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -170,6 +170,9 @@ namespace SixLabors.ImageSharp /// /// Gets the representation of the pixels as a of contiguous memory /// at row beginning from the first pixel on that row. + /// + /// WARNING: Disposing or leaking the underlying image while still working with it's + /// might lead to memory corruption. /// /// The row. /// The @@ -185,6 +188,13 @@ namespace SixLabors.ImageSharp /// /// Gets the representation of the pixels as a in the source image's pixel format /// stored in row major order, if the backing buffer is contiguous. + /// + /// To ensure the memory is contiguous, should be initialized + /// with a that enforces larger contiguous buffers. + /// See . + /// + /// WARNING: Disposing or leaking the underlying image while still working with it's + /// might lead to memory corruption. /// /// The . /// The . diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 2aa9c53945..1a7f84c155 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -206,6 +206,9 @@ namespace SixLabors.ImageSharp /// /// Gets the representation of the pixels as a of contiguous memory /// at row beginning from the first pixel on that row. + /// + /// WARNING: Disposing or leaking the underlying image while still working with it's + /// might lead to memory corruption. /// /// The row. /// The diff --git a/src/ImageSharp/IndexedImageFrame{TPixel}.cs b/src/ImageSharp/IndexedImageFrame{TPixel}.cs index 7668d7600a..d841cbea92 100644 --- a/src/ImageSharp/IndexedImageFrame{TPixel}.cs +++ b/src/ImageSharp/IndexedImageFrame{TPixel}.cs @@ -75,6 +75,9 @@ namespace SixLabors.ImageSharp /// /// Gets the representation of the pixels as a of contiguous memory /// at row beginning from the first pixel on that row. + /// + /// WARNING: Disposing or leaking the underlying while still working with it's + /// might lead to memory corruption. /// /// The row index in the pixel buffer. /// The pixel row as a . diff --git a/src/ImageSharp/Memory/Allocators/Internals/SharedArrayPoolBuffer{T}.cs b/src/ImageSharp/Memory/Allocators/Internals/SharedArrayPoolBuffer{T}.cs index 048cb74333..7edd9f5a74 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/SharedArrayPoolBuffer{T}.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/SharedArrayPoolBuffer{T}.cs @@ -20,6 +20,9 @@ namespace SixLabors.ImageSharp.Memory.Internals this.array = ArrayPool.Shared.Rent(this.lengthInBytes); } + // The worst thing that could happen is that a VERY poorly written user code holding a Span on the stack, + // while loosing the reference to Image (or disposing it) may write to an unrelated ArrayPool array. + // This is an unlikely scenario we mitigate by a warning in GetPixelRowSpan(i) APIs. #pragma warning disable CA2015 // Adding a finalizer to a type derived from MemoryManager may permit memory to be freed while it is still in use by a Span ~SharedArrayPoolBuffer() => this.Dispose(false); #pragma warning restore diff --git a/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs b/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs index d7bb5413db..84b93496da 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs @@ -71,6 +71,10 @@ namespace SixLabors.ImageSharp.Memory.Internals bufferHandle.AssignedToNewOwner(); } + // A VERY poorly written user code holding a Span on the stack, + // while loosing the reference to Image (or disposing it) may write to (now unrelated) pool buffer, + // or cause memory corruption if the underlying UmnanagedMemoryHandle has been released. + // This is an unlikely scenario we mitigate a warning in GetPixelRowSpan(i) APIs. #pragma warning disable CA2015 // Adding a finalizer to a type derived from MemoryManager may permit memory to be freed while it is still in use by a Span ~FinalizableBuffer() => this.Dispose(false); #pragma warning restore