SixLabors/ImageSharp

AccessViolationException and hard crash with animated webp

Erik-White opened this issue · 8 comments

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 DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

ImageSharp version

3.1.2

Other ImageSharp packages and versions

N/A

Environment (Operating system, version and so on)

Windows 11

.NET Framework version

.NET8

Description

Attempting to load the attached image with ImageSharp crashes the process. The image appears to be a normal animated webp that can be opened with e.g. Chrome

Fatal error. Internal CLR error. (0x80131506)
   at System.Runtime.CompilerServices.CastHelpers.StelemRef(System.Array, IntPtr, System.Object)
   at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].AddWithResize(System.__Canon)
   at System.SR.InternalGetResourceString(System.String)
   at System.SR.GetResourceString(System.String)
   at System.IndexOutOfRangeException..ctor()
   at System.Runtime.CompilerServices.CastHelpers.StelemRef(System.Array, IntPtr, System.Object)
   at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].AddWithResize(System.__Canon)
   at System.SR.InternalGetResourceString(System.String)
   at System.SR.GetResourceString(System.String)
   at System.AccessViolationException..ctor()
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.HorizontalUnfilter(System.Span`1<Byte>, System.Span`1<Byte>, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.GradientUnfilter(System.Span`1<Byte>, System.Span`1<Byte>, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.AlphaApplyFilter(Int32, Int32, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.ExtractAlphaRows(SixLabors.ImageSharp.Formats.Webp.Lossless.Vp8LDecoder)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.Decode()
   at SixLabors.ImageSharp.Formats.Webp.Lossy.WebpLossyDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Memory.Buffer2D`1<SixLabors.ImageSharp.PixelFormats.Rgba32>, Int32, Int32, SixLabors.ImageSharp.Formats.Webp.WebpImageInfo, System.Buffers.IMemoryOwner`1<Byte>)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.DecodeImageFrameData[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.Webp.Chunks.WebpFrameData, SixLabors.ImageSharp.Formats.Webp.WebpImageInfo)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.ReadFrame[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, SixLabors.ImageSharp.Image`1<SixLabors.ImageSharp.PixelFormats.Rgba32> ByRef, SixLabors.ImageSharp.ImageFrame`1<SixLabors.ImageSharp.PixelFormats.Rgba32> ByRef, UInt32, UInt32, SixLabors.ImageSharp.Color)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, SixLabors.ImageSharp.Formats.Webp.WebpFeatures, UInt32, UInt32, UInt32)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoderCore.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.IImageDecoderInternals, SixLabors.ImageSharp.Configuration, System.IO.Stream, System.Func`3<SixLabors.ImageSharp.Memory.InvalidMemoryOperationException,SixLabors.ImageSharp.Size,SixLabors.ImageSharp.InvalidImageContentException>, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.IImageDecoderInternals, SixLabors.ImageSharp.Configuration, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.Webp.WebpDecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.SpecializedImageDecoder`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoder.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoder+<>c__DisplayClass1_0.<Decode>b__0(System.IO.Stream)
   at SixLabors.ImageSharp.Formats.ImageDecoder.<WithSeekableStream>g__PeformActionAndResetPosition|11_0[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.IO.Stream, Int64, <>c__DisplayClass11_0`1<System.__Canon> ByRef)
   at SixLabors.ImageSharp.Formats.ImageDecoder.WithSeekableStream[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Func`2<System.IO.Stream,System.__Canon>)
   at SixLabors.ImageSharp.Formats.ImageDecoder.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image+<>c__DisplayClass80_0.<Load>b__0(System.IO.Stream)
   at SixLabors.ImageSharp.Image.WithSeekableStream[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Func`2<System.IO.Stream,System.__Canon>)
   at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Formats.DecoderOptions, System.String)
   at SixLabors.ImageSharp.Image.Load(System.String)
   at Program.<Main>$(System.String[])

Steps to Reproduce

Attempt to load the image
using var image = Image.Load("6FC4D123635F1D1AE8A64F5E9D5CDE4C.webp");

Images

6FC4D123635F1D1AE8A64F5E9D5CDE4C.zip

I had to upload the image in a zip, webp files aren't allowed.

I have also tried the latest preview from your feed 4.0.0-alpha.0.9
It still crashes but with slightly different behaviour, I get a stack overflow instead:

Stack overflow.
Repeat 2383 times:
--------------------------------
   at System.SR.InternalGetResourceString(System.String)
   at System.SR.GetResourceString(System.String)
   at System.ThrowHelper.GetResourceString(System.ExceptionResource)
   at System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument, System.ExceptionResource)
   at System.ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_IndexMustBeLess()
   at System.Array.LastIndexOf[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon[], System.__Canon, Int32, Int32)
   at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].LastIndexOf(System.__Canon, Int32, Int32)
--------------------------------
   at System.SR.InternalGetResourceString(System.String)
   at System.SR.GetResourceString(System.String)
   at System.Array.CopyImpl(System.Array, Int32, System.Array, Int32, Int32, Boolean)
   at System.Array.Copy(System.Array, System.Array, Int32)
   at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].set_Capacity(Int32)
   at System.Collections.Generic.List`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].AddWithResize(System.__Canon)
   at System.SR.InternalGetResourceString(System.String)
   at System.SR.GetResourceString(System.String)
   at System.AccessViolationException..ctor()
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.HorizontalUnfilter(System.Span`1<Byte>, System.Span`1<Byte>, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.GradientUnfilter(System.Span`1<Byte>, System.Span`1<Byte>, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.AlphaApplyFilter(Int32, Int32, System.Span`1<Byte>, Int32)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.ExtractAlphaRows(SixLabors.ImageSharp.Formats.Webp.Lossless.Vp8LDecoder)
   at SixLabors.ImageSharp.Formats.Webp.AlphaDecoder.Decode()
   at SixLabors.ImageSharp.Formats.Webp.Lossy.WebpLossyDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Memory.Buffer2D`1<SixLabors.ImageSharp.PixelFormats.Rgba32>, Int32, Int32, SixLabors.ImageSharp.Formats.Webp.WebpImageInfo, System.Buffers.IMemoryOwner`1<Byte>)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.DecodeImageFrameData[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.Webp.Chunks.WebpFrameData, SixLabors.ImageSharp.Formats.Webp.WebpImageInfo)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.ReadFrame[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, SixLabors.ImageSharp.Image`1<SixLabors.ImageSharp.PixelFormats.Rgba32> ByRef, SixLabors.ImageSharp.ImageFrame`1<SixLabors.ImageSharp.PixelFormats.Rgba32> ByRef, UInt32, UInt32, SixLabors.ImageSharp.Color)
   at SixLabors.ImageSharp.Formats.Webp.WebpAnimationDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, SixLabors.ImageSharp.Formats.Webp.WebpFeatures, UInt32, UInt32, UInt32)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoderCore.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.IO.BufferedReadStream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.IImageDecoderInternals, SixLabors.ImageSharp.Configuration, System.IO.Stream, System.Func`3<SixLabors.ImageSharp.Memory.InvalidMemoryOperationException,SixLabors.ImageSharp.Size,SixLabors.ImageSharp.InvalidImageContentException>, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderUtilities.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.IImageDecoderInternals, SixLabors.ImageSharp.Configuration, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.Webp.WebpDecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.SpecializedImageDecoder`1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.Webp.WebpDecoder.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Threading.CancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoder+<>c__DisplayClass1_0.<Decode>b__0(System.IO.Stream)
   at SixLabors.ImageSharp.Formats.ImageDecoder.<WithSeekableStream>g__PeformActionAndResetPosition|11_0[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.IO.Stream, Int64, <>c__DisplayClass11_0`1<System.__Canon> ByRef)
   at SixLabors.ImageSharp.Formats.ImageDecoder.WithSeekableStream[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Func`2<System.IO.Stream,System.__Canon>)
   at SixLabors.ImageSharp.Formats.ImageDecoder.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image.Decode(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image+<>c__DisplayClass80_0.<Load>b__0(System.IO.Stream)
   at SixLabors.ImageSharp.Image.WithSeekableStream[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream, System.Func`2<System.IO.Stream,System.__Canon>)
   at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Formats.DecoderOptions, System.IO.Stream)
   at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Formats.DecoderOptions, System.String)
   at SixLabors.ImageSharp.Image.Load(System.String)
   at Program.<Main>$(System.String[])

Thanks. I’ll have a look asap.

The issue seems to be caused by frame 35, all previous frames can be decoded.

Here is the frame with the issue:
frame35.zip

webpinfo does not report any issue with the image.

The issue seems to be in HorizontalUnfilter method of the AlphaDecoder and there in the SSE2 part.

Fix was simple enough. An underflow caused by casting (uint)(width - 8) when width < 8.

Fantastic, thank you! Will you be able to break a release that contains this fix soon after it is merged?

Yeah. We've got one more issue I want to fix then I'll push a bugfix release.

Great - thanks for your quick response on fixing this