From c7f3aa40cbee9da1c1f40651645b61b3d243aecd Mon Sep 17 00:00:00 2001 From: Jose Elias dos Santos Date: Thu, 19 Oct 2023 18:41:28 -0300 Subject: [PATCH 1/2] [fix]: Fixed Unknown App0 Marker add profileResolver missing --- .../Formats/Jpeg/Components/Decoder/JFifMarker.cs | 3 ++- .../Jpeg/Components/Decoder/ProfileResolver.cs | 8 ++++++++ .../ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs | 11 +++++++++++ tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Jpg/issues/issue-2564.jpg | 3 +++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/Images/Input/Jpg/issues/issue-2564.jpg diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs index 7e25e945a5..060572fc3f 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs @@ -73,7 +73,8 @@ public static bool TryParse(ReadOnlySpan bytes, out JFifMarker marker) { // Some images incorrectly use JFXX as the App0 marker (Issue 2478) if (ProfileResolver.IsProfile(bytes, ProfileResolver.JFifMarker) - || ProfileResolver.IsProfile(bytes, ProfileResolver.JFxxMarker)) + || ProfileResolver.IsProfile(bytes, ProfileResolver.JFxxMarker) + || ProfileResolver.IsProfile(bytes, ProfileResolver.OSQidMaker)) { byte majorVersion = bytes[5]; byte minorVersion = bytes[6]; diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs index c11679feb1..ed916c205b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs @@ -24,6 +24,14 @@ internal static class ProfileResolver (byte)'J', (byte)'F', (byte)'X', (byte)'X', (byte)'\0' }; + /// + /// Gets the \n[ID or 10 91 73 68 32 specific markers. + /// + public static ReadOnlySpan OSQidMaker => new[] + { + (byte)'\n', (byte)'[', (byte)'I', (byte)'D', (byte)' ' + }; + /// /// Gets the ICC specific markers. /// diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index eaa9f82cbb..f872895227 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -326,6 +326,17 @@ public void Issue2478_DecodeWorks(TestImageProvider provider) image.CompareToOriginal(provider); } + // https://github.com/SixLabors/ImageSharp/discussions/2564 + [Theory] + [WithFile(TestImages.Jpeg.Issues.Issue2564, PixelTypes.Rgba32)] + public void Issue2564_DecodeWorks(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(JpegDecoder.Instance); + image.DebugSave(provider); + image.CompareToOriginal(provider); + } + [Theory] [WithFile(TestImages.Jpeg.Issues.HangBadScan, PixelTypes.L8)] public void DecodeHang(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index c5565bbd85..1d8cfd335b 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -291,6 +291,7 @@ public static class Issues public const string Issue2334_NotEnoughBytesA = "Jpg/issues/issue-2334-a.jpg"; public const string Issue2334_NotEnoughBytesB = "Jpg/issues/issue-2334-b.jpg"; public const string Issue2478_JFXX = "Jpg/issues/issue-2478-jfxx.jpg"; + public const string Issue2564 = "Jpg/issues/issue-2564.jpg"; public const string HangBadScan = "Jpg/issues/Hang_C438A851.jpg"; public static class Fuzz diff --git a/tests/Images/Input/Jpg/issues/issue-2564.jpg b/tests/Images/Input/Jpg/issues/issue-2564.jpg new file mode 100644 index 0000000000..2f0b581032 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/issue-2564.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08f215c777b6fe8e315f18b7f93611c90fa86fefb8e3d37181890afb3068d8bd +size 939150 From 48cecd3c184fb686f7138257cc08517ec6b49aa4 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 29 Nov 2023 17:21:22 +1000 Subject: [PATCH 2/2] Make JFIF marker optional --- .../Formats/Jpeg/Components/Decoder/JFifMarker.cs | 3 +-- .../Formats/Jpeg/Components/Decoder/ProfileResolver.cs | 8 -------- src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs | 5 +---- tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs | 2 +- 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs index 060572fc3f..7e25e945a5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs @@ -73,8 +73,7 @@ public static bool TryParse(ReadOnlySpan bytes, out JFifMarker marker) { // Some images incorrectly use JFXX as the App0 marker (Issue 2478) if (ProfileResolver.IsProfile(bytes, ProfileResolver.JFifMarker) - || ProfileResolver.IsProfile(bytes, ProfileResolver.JFxxMarker) - || ProfileResolver.IsProfile(bytes, ProfileResolver.OSQidMaker)) + || ProfileResolver.IsProfile(bytes, ProfileResolver.JFxxMarker)) { byte majorVersion = bytes[5]; byte minorVersion = bytes[6]; diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs index ed916c205b..c11679feb1 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs @@ -24,14 +24,6 @@ internal static class ProfileResolver (byte)'J', (byte)'F', (byte)'X', (byte)'X', (byte)'\0' }; - /// - /// Gets the \n[ID or 10 91 73 68 32 specific markers. - /// - public static ReadOnlySpan OSQidMaker => new[] - { - (byte)'\n', (byte)'[', (byte)'I', (byte)'D', (byte)' ' - }; - /// /// Gets the ICC specific markers. /// diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 83a828caaf..ccace190f9 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -753,10 +753,7 @@ private void ProcessApplicationHeaderMarker(BufferedReadStream stream, int remai Span temp = stackalloc byte[2 * 16 * 4]; stream.Read(temp, 0, JFifMarker.Length); - if (!JFifMarker.TryParse(temp, out this.jFif)) - { - JpegThrowHelper.ThrowNotSupportedException("Unknown App0 Marker - Expected JFIF."); - } + _ = JFifMarker.TryParse(temp, out this.jFif); remaining -= JFifMarker.Length; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index f872895227..deea9217f0 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -330,7 +330,7 @@ public void Issue2478_DecodeWorks(TestImageProvider provider) [Theory] [WithFile(TestImages.Jpeg.Issues.Issue2564, PixelTypes.Rgba32)] public void Issue2564_DecodeWorks(TestImageProvider provider) - where TPixel : unmanaged, IPixel + where TPixel : unmanaged, IPixel { using Image image = provider.GetImage(JpegDecoder.Instance); image.DebugSave(provider);