Skip to content

Correctly handle Multiple SOF with SOS data #3118

@JimBobSquarePants

Description

@JimBobSquarePants

Our web service accepts images and stores them for background processing. We use Image.Identify in combination with a couple of other checks to try to detect image files that aren't valid so we can reject them before storage. That detection happens through this method:

public static bool TryIdentify(Span<byte> imageBytes, out ImageInfo imageInfo)
{
	try
	{
		imageInfo = Image.Identify(imageBytes);
	}
	catch (Exception e) when (e is NotSupportedException || e is InvalidImageContentException || e is UnknownImageFormatException)
	{
		imageInfo = null;
		
		return false;
	}
	
	return true;
}

During background processing we ran across an image that throws the following exception from Image.Load(...):

SixLabors.ImageSharp.InvalidImageContentException: Multiple SOF markers. Only single frame jpegs supported.
   at SixLabors.ImageSharp.Formats.Jpeg.JpegThrowHelper.ThrowInvalidImageContentException(String errorMessage)
   at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.ProcessStartOfFrameMarker(BufferedReadStream stream, Int32 remaining, JpegFileMarker& frameMarker, ComponentType decodingComponentType, Boolean metadataOnly)
   at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.ParseStream(BufferedReadStream stream, SpectralConverter spectralConverter, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.Decode[TPixel](BufferedReadStream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoderCore.Decode[TPixel](Configuration configuration, Stream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoder.Decode[TPixel](JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoder.Decode(JpegDecoderOptions options, Stream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.SpecializedImageDecoder`1.Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
   at SixLabors.ImageSharp.Formats.ImageDecoder.<>c__DisplayClass1_0.<Decode>b__0(Stream s)
   at SixLabors.ImageSharp.Formats.ImageDecoder.<WithSeekableStream>g__PerformActionAndResetPosition|11_0[T](Stream s, Int64 position, <>c__DisplayClass11_0`1&)
   at SixLabors.ImageSharp.Formats.ImageDecoder.WithSeekableStream[T](DecoderOptions options, Stream stream, Func`2 action)
   at SixLabors.ImageSharp.Formats.ImageDecoder.Decode(DecoderOptions options, Stream stream)
   at SixLabors.ImageSharp.Image.Decode(DecoderOptions options, Stream stream)
   at SixLabors.ImageSharp.Image.<>c__DisplayClass80_0.<Load>b__0(Stream s)
   at SixLabors.ImageSharp.Image.WithSeekableStream[T](DecoderOptions options, Stream stream, Func`2 action)
   at SixLabors.ImageSharp.Image.Load(DecoderOptions options, Stream stream)
   at SixLabors.ImageSharp.Image.Load(DecoderOptions options, ReadOnlySpan`1 buffer)
   at SixLabors.ImageSharp.Image.Load(ReadOnlySpan`1 buffer)

We're trying to figure out a way we could have rejected this image at upload time and hit a wall. Is there something we can do? Or is this just one of those problems that can only be found by fully decoding the image?

Originally posted by @natehitze-eventlink in #3117

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions