-
-
Notifications
You must be signed in to change notification settings - Fork 887
Description
Prerequisites
- I have written a descriptive issue title
- I have verified that I am running the latest version of ImageSharp
- I have verified if the problem exist in both
DEBUGandRELEASEmode - I have searched open and closed issues to ensure it has not already been reported
Description
Image& Image underlying frames aren't disposed correctly, can be accessed after parent image disposal and can be mutated like it's a valid instance.
Frames access properties do not ensure that they are not disposed:
ImageSharp/src/ImageSharp/Image{TPixel}.cs
Line 144 in 993f96e
| protected override ImageFrameCollection NonGenericFrameCollection => this.Frames; |
ImageSharp/src/ImageSharp/Image{TPixel}.cs
Line 149 in 993f96e
| public new ImageFrameCollection<TPixel> Frames { get; } |
Dispose method does not nullify Frames property:
ImageSharp/src/ImageSharp/Image{TPixel}.cs
Lines 258 to 271 in 993f96e
| protected override void Dispose(bool disposing) | |
| { | |
| if (this.isDisposed) | |
| { | |
| return; | |
| } | |
| if (disposing) | |
| { | |
| this.Frames.Dispose(); | |
| } | |
| this.isDisposed = true; | |
| } |
Nearly all ImageFrameCollection methods affected leading to odd situations:
var image = Image.Load<ImageSharp.PixelFormats.Rgba32>(...);
var someOtherFrame = image.Frames.RootFrame.Clone();
image.Dispose();
// accepting root frame
var rootFromImage = image.GetRootFramePixelBuffer(); // throws ObjectDisposed as expected
var rootFromFrames = image.Frames.RootFrame; // returns null
// mutation still works
image.Frames.AddFrame(someOtherFrame);
// and this mutation can lead to image returning spans like it was never disposed
var span = image.GetPixelRowSpan(0);Last line works kinda like expected because everything else is broken
*All above also works for base Image class
Steps to Reproduce
Use this code snippet for any image:
var image = Image.Load<ImageSharp.PixelFormats.Rgba32>("path");
var someOtherFrame = image.Frames.RootFrame.Clone();
image.Dispose();
var rootFromFrames = image.Frames.RootFrame;
image.Frames.AddFrame(someOtherFrame);
var span = image.GetPixelRowSpan(0);