diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwString.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwString.cs index e6895d67cd..e8a62e754e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwString.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwString.cs @@ -69,25 +69,33 @@ public class LzwString return 0; } - if (this.Length == 1) + int available = buffer.Length - offset; + if (available <= 0) { - buffer[offset] = this.value; - return 1; + return 0; + } + + int numToWrite = this.Length; + if (numToWrite > available) + { + numToWrite = available; } LzwString e = this; - int endIdx = this.Length - 1; - if (endIdx >= buffer.Length) + + // if string is too long, skip bytes at the end + int toSkip = this.Length - numToWrite; + for (int i = 0; i < toSkip; i++) { - TiffThrowHelper.ThrowImageFormatException("Error reading lzw compressed stream. Either pixel buffer to write to is to small or code length is invalid!"); + e = e.previous; } - for (int i = endIdx; i >= 0; i--) + for (int i = numToWrite - 1; i >= 0; i--) { buffer[offset + i] = e.value; e = e.previous; } - return this.Length; + return numToWrite; } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 5dd1f7884f..26dc4f5878 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -833,4 +833,9 @@ public class TiffDecoderTests : TiffDecoderBaseTester [WithFile(ExtraSamplesUnspecified, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_ExtraSamplesUnspecified(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + + [Theory] + [WithFile(Issue2983, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_Issue2983(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 9a5cfc706e..3e5b3b7120 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -1164,6 +1164,7 @@ public static class TestImages public const string IptcData = "Tiff/iptc.tiff"; public const string Issue2909 = "Tiff/Issues/Issue2909.tiff"; + public const string Issue2983 = "Tiff/Issues/Issue2983.tiff"; public static readonly string[] Multiframes = [MultiframeDeflateWithPreview, MultiframeLzwPredictor /*, MultiFrameDifferentSize, MultiframeDifferentSizeTiled, MultiFrameDifferentVariants,*/ ]; diff --git a/tests/Images/Input/Tiff/Issues/Issue2983.tiff b/tests/Images/Input/Tiff/Issues/Issue2983.tiff new file mode 100644 index 0000000000..7332ca42a9 --- /dev/null +++ b/tests/Images/Input/Tiff/Issues/Issue2983.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bfe1d8660d11111cdf2674aedc43c1362dc8c2ecfab9b74b43a06c7c195863e +size 13311100