Skip to content

Commit 9b8256c

Browse files
authored
Merge branch 'main' into bp/extrasamples2
2 parents c6544eb + f970634 commit 9b8256c

File tree

7 files changed

+47
-13
lines changed

7 files changed

+47
-13
lines changed

src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ private void ProcessApplicationHeaderMarker(BufferedReadStream stream, int remai
677677
}
678678

679679
/// <summary>
680-
/// Processes the App1 marker retrieving any stored metadata
680+
/// Processes the App1 marker retrieving any stored metadata.
681681
/// </summary>
682682
/// <param name="stream">The input stream.</param>
683683
/// <param name="remaining">The remaining bytes in the segment block.</param>
@@ -687,7 +687,7 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining)
687687
const int XmpMarkerLength = 29;
688688
if (remaining < ExifMarkerLength || this.IgnoreMetadata)
689689
{
690-
// Skip the application header length
690+
// Skip the application header length.
691691
stream.Skip(remaining);
692692
return;
693693
}
@@ -697,12 +697,12 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining)
697697
JpegThrowHelper.ThrowInvalidImageContentException("Bad App1 Marker length.");
698698
}
699699

700-
// XMP marker is the longest, so read at least that many bytes into temp.
700+
// XMP marker is the longer then the EXIF marker, so first try read the EXIF marker bytes.
701701
stream.Read(this.temp, 0, ExifMarkerLength);
702+
remaining -= ExifMarkerLength;
702703

703704
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.ExifMarker))
704705
{
705-
remaining -= ExifMarkerLength;
706706
this.hasExif = true;
707707
byte[] profile = new byte[remaining];
708708
stream.Read(profile, 0, remaining);
@@ -713,7 +713,7 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining)
713713
}
714714
else
715715
{
716-
// If the EXIF information exceeds 64K, it will be split over multiple APP1 markers
716+
// If the EXIF information exceeds 64K, it will be split over multiple APP1 markers.
717717
this.ExtendProfile(ref this.exifData, profile);
718718
}
719719

@@ -722,9 +722,10 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining)
722722

723723
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker.Slice(0, ExifMarkerLength)))
724724
{
725-
stream.Read(this.temp, 0, XmpMarkerLength - ExifMarkerLength);
726-
remaining -= XmpMarkerLength;
727-
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker.Slice(ExifMarkerLength)))
725+
int remainingXmpMarkerBytes = XmpMarkerLength - ExifMarkerLength;
726+
stream.Read(this.temp, ExifMarkerLength, remainingXmpMarkerBytes);
727+
remaining -= remainingXmpMarkerBytes;
728+
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker))
728729
{
729730
this.hasXmp = true;
730731
byte[] profile = new byte[remaining];
@@ -736,7 +737,7 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining)
736737
}
737738
else
738739
{
739-
// If the XMP information exceeds 64K, it will be split over multiple APP1 markers
740+
// If the XMP information exceeds 64K, it will be split over multiple APP1 markers.
740741
this.ExtendProfile(ref this.xmpData, profile);
741742
}
742743

src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal ExifValue(ExifValue other)
2929
{
3030
// All array types are value types so Clone() is sufficient here.
3131
var array = (Array)other.GetValue();
32-
this.TrySetValue(array.Clone());
32+
this.TrySetValue(array?.Clone());
3333
}
3434
}
3535

tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.IO;
66
using System.Runtime.CompilerServices;
7-
using System.Text;
87
using SixLabors.ImageSharp.Formats;
98
using SixLabors.ImageSharp.Formats.Jpeg;
109
using SixLabors.ImageSharp.Metadata;
@@ -302,6 +301,19 @@ public void Decode_WithInvalidIptcTag_DoesNotThrowException<TPixel>(TestImagePro
302301
Assert.Null(ex);
303302
}
304303

304+
[Theory]
305+
[WithFile(TestImages.Jpeg.Issues.ExifNullArrayTag, PixelTypes.Rgba32)]
306+
public void Clone_WithNullRationalArrayTag_DoesNotThrowException<TPixel>(TestImageProvider<TPixel> provider)
307+
where TPixel : unmanaged, IPixel<TPixel>
308+
{
309+
Exception ex = Record.Exception(() =>
310+
{
311+
using Image<TPixel> image = provider.GetImage(JpegDecoder);
312+
var clone = image.Metadata.ExifProfile.DeepClone();
313+
});
314+
Assert.Null(ex);
315+
}
316+
305317
[Fact]
306318
public void EncodedStringTags_WriteAndRead()
307319
{

tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
namespace SixLabors.ImageSharp.Tests.Formats.Jpg
2222
{
2323
// TODO: Scatter test cases into multiple test classes
24-
[Trait("Format", "Jpg")]
24+
[Trait("Format", "Jpg")]
2525
public partial class JpegDecoderTests
2626
{
2727
public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.Bgr24 | PixelTypes.RgbaVector;
@@ -65,7 +65,7 @@ private static bool SkipTest(ITestImageProvider provider)
6565

6666
private ITestOutputHelper Output { get; }
6767

68-
private static JpegDecoder JpegDecoder => new JpegDecoder();
68+
private static JpegDecoder JpegDecoder => new();
6969

7070
[Fact]
7171
public void ParseStream_BasicPropertiesAreCorrect()
@@ -213,6 +213,19 @@ public void Issue1732_DecodesWithRgbColorSpace<TPixel>(TestImageProvider<TPixel>
213213
}
214214
}
215215

216+
// https://github.com/SixLabors/ImageSharp/issues/2057
217+
[Theory]
218+
[WithFile(TestImages.Jpeg.Issues.Issue2057App1Parsing, PixelTypes.Rgba32)]
219+
public void Issue2057_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
220+
where TPixel : unmanaged, IPixel<TPixel>
221+
{
222+
using (Image<TPixel> image = provider.GetImage(JpegDecoder))
223+
{
224+
image.DebugSave(provider);
225+
image.CompareToOriginal(provider);
226+
}
227+
}
228+
216229
// DEBUG ONLY!
217230
// The PDF.js output should be saved by "tests\ImageSharp.Tests\Formats\Jpg\pdfjs\jpeg-converter.htm"
218231
// into "\tests\Images\ActualOutput\JpegDecoderTests\"

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ public static class Issues
262262
public const string MalformedUnsupportedComponentCount = "Jpg/issues/issue-1900-malformed-unsupported-255-components.jpg";
263263
public const string MultipleApp01932 = "Jpg/issues/issue-1932-app0-resolution.jpg";
264264
public const string InvalidIptcTag = "Jpg/issues/Issue1942InvalidIptcTag.jpg";
265+
public const string Issue2057App1Parsing = "Jpg/issues/Issue2057-App1Parsing.jpg";
266+
public const string ExifNullArrayTag = "Jpg/issues/issue-2056-exif-null-array.jpg";
265267

266268
public static class Fuzz
267269
{
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)