SixLabors / ImageSharp

:camera: A modern, cross-platform, 2D Graphics library for .NET
https://sixlabors.com/products/imagesharp/
Other
7.31k stars 846 forks source link

Unexpected ArgumentOutOfRangeException at SixLabors.ImageSharp.Image.InternalDetectFormat(Configuration, Stream) #2634

Closed Poker-sang closed 7 months ago

Poker-sang commented 7 months ago

Prerequisites

ImageSharp version

3.1.1

Other ImageSharp packages and versions

No

Environment (Operating system, version and so on)

Windows 11 (22631.2861)

.NET Framework version

8.0

Description

at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) at System.IO.BufferedStream.set_Position(Int64 value) at SixLabors.ImageSharp.Image.InternalDetectFormat(Configuration configuration, Stream stream) at SixLabors.ImageSharp.Image.DiscoverDecoder(DecoderOptions options, Stream stream) at SixLabors.ImageSharp.Image.DecodeAsync[TPixel](DecoderOptions options, Stream stream, CancellationToken cancellationToken) at SixLabors.ImageSharp.Image.<>c__DisplayClass86_0`1.b0(Stream s, CancellationToken ct) at SixLabors.ImageSharp.Image.d88`1.MoveNext() at Pixeval.Util.IO.IoHelper.d__39.MoveNext() at C:\WorkSpace\Pixeval\src\Pixeval\Util\IO\IOHelper.Imaging.cs: Line 187

Steps to Reproduce

imageStream is Windows.Storage.Streams.IRandomAccessStream

The Exception is not always thrown.

try
{
    var a = imageStream.Position; // a = 1700
    var b = imageStream.Size; // b = 1700
    var h = imageStream.CanRead; // h = true
    var i = imageStream.CanWrite; // i = false
    imageStream.Seek(0);
    var c = imageStream.Position; // c = 0
    var d = imageStream.Size; // d = 1700
    using var image = await Image.LoadAsync<Bgra32>(imageStream.AsStreamForRead()); // Exception thrown
    var softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, image.Width, image.Height, BitmapAlphaMode.Premultiplied);
    var buffer = new byte[4 * image.Width * image.Height];
    image.CopyPixelDataTo(buffer);
    softwareBitmap.CopyFromBuffer(buffer.AsBuffer());
    return softwareBitmap;
}
catch (Exception e) // Non-negative number required. (Parameter 'value')
{
    Debugger.Break();
    Console.WriteLine(e);
    throw;
}

Images

No response

JimBobSquarePants commented 7 months ago

There isn’t enough here to reproduce a potential issue I’m afraid. We’d need a reduced sample running within an application with an image known to trigger the exception.

Poker-sang commented 7 months ago

I am sorry but this issue does not always happen. I am trying to find a way to reproduce the problem consistently.

Poker-sang commented 7 months ago

Looks like AsStreamForRead() accidentally makes Stream.Position negative sometimes. It's not a bug from ImageSharp actually. Should we check Stream.Position positive in Image.Load to avoid this, and better help users locate bugs?

image

JimBobSquarePants commented 7 months ago

In the years I’ve been developing the library, I’ve never seen a negative stream position before.

Poker-sang commented 7 months ago

Me neither. However it actually happened in my screenshot.