diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 3e3d6d0e27..41136bfd8a 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -62,8 +62,6 @@ jobs:
needs: WarmLFS
strategy:
matrix:
- isARM:
- - ${{ contains(github.event.pull_request.labels.*.name, 'arch:arm32') || contains(github.event.pull_request.labels.*.name, 'arch:arm64') }}
options:
- os: ubuntu-latest
framework: net9.0
@@ -121,10 +119,6 @@ jobs:
sdk: 8.0.x
runtime: -x64
codecov: false
- exclude:
- - isARM: false
- options:
- os: buildjet-4vcpu-ubuntu-2204-arm
runs-on: ${{ matrix.options.os }}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 0ad78b9035..7825955e7a 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -71,6 +71,11 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
///
private bool hasAdobeMarker;
+ ///
+ /// Whether the image has a SOS marker.
+ ///
+ private bool hasSOSMarker;
+
///
/// Contains information about the JFIF marker.
///
@@ -197,6 +202,12 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
{
using SpectralConverter spectralConverter = new(this.configuration, this.resizeMode == JpegDecoderResizeMode.ScaleOnly ? null : this.Options.TargetSize);
this.ParseStream(stream, spectralConverter, cancellationToken);
+
+ if (!this.hasSOSMarker)
+ {
+ JpegThrowHelper.ThrowInvalidImageContentException("Missing SOS marker.");
+ }
+
this.InitExifProfile();
this.InitIccProfile();
this.InitIptcProfile();
@@ -215,6 +226,12 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
protected override ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
this.ParseStream(stream, spectralConverter: null, cancellationToken);
+
+ if (!this.hasSOSMarker)
+ {
+ JpegThrowHelper.ThrowInvalidImageContentException("Missing SOS marker.");
+ }
+
this.InitExifProfile();
this.InitIccProfile();
this.InitIptcProfile();
@@ -403,6 +420,8 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
break;
case JpegConstants.Markers.SOS:
+
+ this.hasSOSMarker = true;
if (!metadataOnly)
{
this.ProcessStartOfScanMarker(stream, markerContentByteSize);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index 71753bf9ca..3fd55eb915 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -417,4 +417,20 @@ public partial class JpegDecoderTests
image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
}
+
+ // https://github.com/SixLabors/ImageSharp/issues/2948
+ [Theory]
+ [WithFile(TestImages.Jpeg.Issues.Issue2948, PixelTypes.Rgb24)]
+ public void Issue2948_No_SOS_Decode_Throws_InvalidImageContentException(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ => Assert.Throws(() =>
+ {
+ using Image image = provider.GetImage(JpegDecoder.Instance);
+ });
+
+ // https://github.com/SixLabors/ImageSharp/issues/2948
+ [Theory]
+ [InlineData(TestImages.Jpeg.Issues.Issue2948)]
+ public void Issue2948_No_SOS_Identify_Throws_InvalidImageContentException(string imagePath)
+ => Assert.Throws(() => _ = Image.Identify(TestFile.Create(imagePath).Bytes));
}
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 94dcd2b7b9..bc699da88e 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -348,6 +348,7 @@ public static class TestImages
public const string Issue2638 = "Jpg/issues/Issue2638.jpg";
public const string Issue2758 = "Jpg/issues/issue-2758.jpg";
public const string Issue2857 = "Jpg/issues/issue-2857-subsub-ifds.jpg";
+ public const string Issue2948 = "Jpg/issues/issue-2948-sos.jpg";
public static class Fuzz
{
diff --git a/tests/Images/Input/Jpg/issues/issue-2948-sos.jpg b/tests/Images/Input/Jpg/issues/issue-2948-sos.jpg
new file mode 100644
index 0000000000..d210e87e52
--- /dev/null
+++ b/tests/Images/Input/Jpg/issues/issue-2948-sos.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ad9c3a6babb41c5aa2a46fbfe74ed5482028c73f48531cf144e1e324ca7988b3
+size 103789