SkiaSharp icon indicating copy to clipboard operation
SkiaSharp copied to clipboard

[BUG] SKManagedStream crash loading bmp files introduced in 2.80.3

Open jermarti opened this issue 3 years ago • 6 comments

Description

We use C# streams to load BMP images from disk, and hand those streams directly to SKBitmap.Decode(). After updating from 2.80.2 to 2.80.3 this pattern is now crashing with the exception: System.ArgumentNullException: 'Value cannot be null. Parameter name: buffer'

I've tracked it down to loading BMPs (JPG loading with the same code works fine) and only when the load pathway goes through SKManagedStream. Any method that uses this class to load this type of file (whether I make the SKManagedStream from the C# stream and give it to the Decode() function, or hand the Decode() function the C# stream directly) crashes loading BMPs.

Here is the stack track:

SkiaSharp.dll!SkiaSharp.SKManagedStream.OnReadManagedStream(System.IntPtr buffer, System.IntPtr size)	Unknown
SkiaSharp.dll!SkiaSharp.SKAbstractManagedStream.ReadInternal(System.IntPtr s, void* context, void* buffer, System.IntPtr size)	Unknown
[Native to Managed Transition]	
[Managed to Native Transition]	
SkiaSharp.dll!SkiaSharp.SKCodec.GetPixels(SkiaSharp.SKImageInfo info, System.IntPtr pixels, int rowBytes, SkiaSharp.SKCodecOptions options)	Unknown
SkiaSharp.dll!SkiaSharp.SKCodec.GetPixels(SkiaSharp.SKImageInfo info, System.IntPtr pixels)	Unknown
SkiaSharp.dll!SkiaSharp.SKBitmap.Decode(SkiaSharp.SKCodec codec, SkiaSharp.SKImageInfo bitmapInfo)	Unknown
SkiaSharp.dll!SkiaSharp.SKBitmap.Decode(SkiaSharp.SKCodec codec)	Unknown
SkiaSharp.dll!SkiaSharp.SKBitmap.Decode(SkiaSharp.SKStream stream)	Unknown

Notably, if I either read the BMP into a byte array or an SDKData first the same file decodes fine (using the following code) SKData fileSKData = SKData.Create(fileStream); SKBitmap returnBitmap = SKBitmap.Decode(fileSKData);

Code // This throws the exception System.ArgumentNullException: 'Value cannot be null. Parameter name: buffer' using (SKManagedStream sKManagedStream = new SKManagedStream(fileStream)) { // This crashes before returning from Decode() SKBitmap returnBitmap = SKBitmap.Decode(sKManagedStream); }

Expected Behavior

A bitmap can be loaded via a C# stream

Actual Behavior

The code crashes when loading a bmp but only through SKManagedStream

Basic Information

  • Version with issue: 2.80.3
  • Last known good version: 2.80.2
  • IDE: MSVC 2019
  • Platform Target Frameworks:
    • UWP: 19041
    • Windows Classic: Version 10.0.19043 Build 19043
  • Target Devices: Windows Desktop

jermarti avatar Jul 29 '21 18:07 jermarti

I can confirm the same with 2.80.3. Fixed by rolling back to 2.80.2. Also this seems to be related to #1551

using var codec = SKCodec.Create(source); 
....
Unhandled exception. Unhandled exception. Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'buffer')
   at SkiaSharp.SKManagedStream.OnReadManagedStream(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKManagedStream.OnRead(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKAbstractManagedStream.ReadInternal(IntPtr s, Void* context, Void* buffer, IntPtr size)System.ArgumentNullException: Value cannot be null. (Parameter 'buffer')
   at SkiaSharp.SKManagedStream.OnReadManagedStream(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKManagedStream.OnRead(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKAbstractManagedStream.ReadInternal(IntPtr s, Void* context, Void* buffer, IntPtr size)System.ArgumentNullException: Value cannot be null. (Parameter 'buffer')
   at SkiaSharp.SKManagedStream.OnReadManagedStream(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKManagedStream.OnRead(IntPtr buffer, IntPtr size)
   at SkiaSharp.SKAbstractManagedStream.ReadInternal(IntPtr s, Void* context, Void* buffer, IntPtr size)

lordtct avatar Aug 03 '21 04:08 lordtct

Experiencing same problem on version 2.80.3, but only on very specific device (Huawei Nova 5T in my case). Can't repro myself, I don't have the device but this is Visual Studio App Center report:

Exception:

SKManagedStream.OnReadManagedStream (System.IntPtr buffer, System.IntPtr size)
System.ArgumentNullException: Value cannot be null. Parameter name: buffer

SKManagedStream.OnReadManagedStream (System.IntPtr buffer, System.IntPtr size)
SKManagedStream.OnRead (System.IntPtr buffer, System.IntPtr size)
SKAbstractManagedStream.ReadInternal (System.IntPtr s, System.Void* context, System.Void* buffer, System.IntPtr size)
(wrapper native-to-managed) SkiaSharp.SKAbstractManagedStream.ReadInternal(intptr,void*,void*,intptr)
(wrapper managed-to-native) SkiaSharp.SkiaApi.sk_codec_new_from_stream(intptr,SkiaSharp.SKCodecResult*)
SKCodec.Create (SkiaSharp.SKStream stream, SkiaSharp.SKCodecResult& result)
SKCodec.Create (SkiaSharp.SKStream stream)

Code:

using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    using (var inputStream = new SKManagedStream(file))
    {
        using (var codec = SKCodec.Create(inputStream)) // Crashes here, most likely
...

deli-nik avatar Aug 09 '21 13:08 deli-nik

I too am experiencing this issue but with JPGs and only some of them.

using (var input = File.OpenRead(file.FilePath))
                {
                    using (var inputStream = new SKManagedStream(input))
                    {
                        using (var original = SKBitmap.Decode(inputStream))` <-- errors here

julianadormon avatar Jan 17 '22 18:01 julianadormon

Have the same issue. Pixel emulator works fine. But physical Samsung Galaxy S9+ throws this error. Rolled back to 2.80.2 and it works on both.

mtyeager avatar Mar 10 '22 16:03 mtyeager

Any updates on this one?

theolivenbaum avatar May 09 '22 16:05 theolivenbaum

I encounter the same problem after upgrading from 2.80.2

Socolin avatar Jun 26 '22 04:06 Socolin

Hi folks. Sorry it took forever to fix this - especially since it was so simple and totally my fault. I will try get a package out ASAP after this merges: https://github.com/mono/SkiaSharp/pull/2265

mattleibow avatar Sep 29 '22 04:09 mattleibow