Skip to content

Commit d02854f

Browse files
authored
Merge branch 'main' into bp/Issue2132
2 parents 3af2dd7 + e7a10b0 commit d02854f

File tree

8 files changed

+67
-46
lines changed

8 files changed

+67
-46
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"

.github/workflows/build-and-test.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
git config --global core.longpaths true
5959
6060
- name: Git Checkout
61-
uses: actions/checkout@v2
61+
uses: actions/checkout@v3
6262
with:
6363
fetch-depth: 0
6464
submodules: recursive
@@ -68,7 +68,7 @@ jobs:
6868
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
6969

7070
- name: Git Setup LFS Cache
71-
uses: actions/cache@v2
71+
uses: actions/cache@v3
7272
id: lfs-cache
7373
with:
7474
path: .git/lfs
@@ -81,15 +81,15 @@ jobs:
8181
uses: NuGet/setup-nuget@v1
8282

8383
- name: NuGet Setup Cache
84-
uses: actions/cache@v2
84+
uses: actions/cache@v3
8585
id: nuget-cache
8686
with:
8787
path: ~/.nuget
8888
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }}
8989
restore-keys: ${{ runner.os }}-nuget-
9090

9191
- name: DotNet Setup
92-
uses: actions/setup-dotnet@v1
92+
uses: actions/setup-dotnet@v2
9393
with:
9494
include-prerelease: true
9595
dotnet-version: |
@@ -127,7 +127,7 @@ jobs:
127127
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit
128128

129129
- name: Export Failed Output
130-
uses: actions/upload-artifact@v2
130+
uses: actions/upload-artifact@v3
131131
if: failure()
132132
with:
133133
name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip
@@ -148,7 +148,7 @@ jobs:
148148
git config --global core.longpaths true
149149
150150
- name: Git Checkout
151-
uses: actions/checkout@v2
151+
uses: actions/checkout@v3
152152
with:
153153
fetch-depth: 0
154154
submodules: recursive
@@ -157,7 +157,7 @@ jobs:
157157
uses: NuGet/setup-nuget@v1
158158

159159
- name: NuGet Setup Cache
160-
uses: actions/cache@v2
160+
uses: actions/cache@v3
161161
id: nuget-cache
162162
with:
163163
path: ~/.nuget

.github/workflows/code-coverage.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
git config --global core.longpaths true
2525
2626
- name: Git Checkout
27-
uses: actions/checkout@v2
27+
uses: actions/checkout@v3
2828
with:
2929
fetch-depth: 0
3030
submodules: recursive
@@ -34,7 +34,7 @@ jobs:
3434
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
3535

3636
- name: Git Setup LFS Cache
37-
uses: actions/cache@v2
37+
uses: actions/cache@v3
3838
id: lfs-cache
3939
with:
4040
path: .git/lfs
@@ -47,15 +47,15 @@ jobs:
4747
uses: NuGet/setup-nuget@v1
4848

4949
- name: NuGet Setup Cache
50-
uses: actions/cache@v2
50+
uses: actions/cache@v3
5151
id: nuget-cache
5252
with:
5353
path: ~/.nuget
5454
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }}
5555
restore-keys: ${{ runner.os }}-nuget-
5656

5757
- name: DotNet Setup
58-
uses: actions/setup-dotnet@v1
58+
uses: actions/setup-dotnet@v2
5959
with:
6060
dotnet-version: |
6161
6.0.x
@@ -74,14 +74,14 @@ jobs:
7474
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit
7575

7676
- name: Export Failed Output
77-
uses: actions/upload-artifact@v2
77+
uses: actions/upload-artifact@v3
7878
if: failure()
7979
with:
8080
name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip
8181
path: tests/Images/ActualOutput/
8282

8383
- name: Codecov Update
84-
uses: codecov/codecov-action@v1
84+
uses: codecov/codecov-action@v3
8585
if: matrix.options.codecov == true && startsWith(github.repository, 'SixLabors')
8686
with:
8787
flags: unittests

src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBitReader.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,14 @@ private ulong GetBytes()
155155
c = this.ReadStream();
156156
}
157157

158+
// Found a marker
158159
// We accept multiple FF bytes followed by a 0 as meaning a single FF data byte.
159-
// This data pattern is not valid according to the standard.
160+
// even though it's considered 'invalid' according to the specs.
160161
if (c != 0)
161162
{
162-
this.Marker = (byte)c;
163+
// It's a trick so we won't read past actual marker
163164
this.badData = true;
165+
this.Marker = (byte)c;
164166
this.MarkerPosition = this.stream.Position - 2;
165167
}
166168
}
@@ -199,7 +201,6 @@ public bool FindNextMarker()
199201
if (b != 0)
200202
{
201203
this.Marker = (byte)b;
202-
this.badData = true;
203204
this.MarkerPosition = this.stream.Position - 2;
204205
return true;
205206
}

src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -164,38 +164,38 @@ public JpegDecoderCore(Configuration configuration, IJpegDecoderOptions options)
164164
/// <summary>
165165
/// Finds the next file marker within the byte stream.
166166
/// </summary>
167-
/// <param name="marker">The buffer to read file markers to.</param>
168167
/// <param name="stream">The input stream.</param>
169-
/// <returns>The <see cref="JpegFileMarker"/></returns>
170-
public static JpegFileMarker FindNextFileMarker(byte[] marker, BufferedReadStream stream)
168+
/// <returns>The <see cref="JpegFileMarker"/>.</returns>
169+
public static JpegFileMarker FindNextFileMarker(BufferedReadStream stream)
171170
{
172-
int value = stream.Read(marker, 0, 2);
173-
174-
if (value == 0)
171+
while (true)
175172
{
176-
return new JpegFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
177-
}
173+
int b = stream.ReadByte();
174+
if (b == -1)
175+
{
176+
return new JpegFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
177+
}
178178

179-
if (marker[0] == JpegConstants.Markers.XFF)
180-
{
181-
// According to Section B.1.1.2:
182-
// "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code 0xFF."
183-
int m = marker[1];
184-
while (m == JpegConstants.Markers.XFF)
179+
// Found a marker.
180+
if (b == JpegConstants.Markers.XFF)
185181
{
186-
int suffix = stream.ReadByte();
187-
if (suffix == -1)
182+
while (b == JpegConstants.Markers.XFF)
188183
{
189-
return new JpegFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
184+
// Loop here to discard any padding FF bytes on terminating marker.
185+
b = stream.ReadByte();
186+
if (b == -1)
187+
{
188+
return new JpegFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
189+
}
190190
}
191191

192-
m = suffix;
192+
// Found a valid marker. Exit loop
193+
if (b is not 0 and (< JpegConstants.Markers.RST0 or > JpegConstants.Markers.RST7))
194+
{
195+
return new JpegFileMarker((byte)(uint)b, stream.Position - 2);
196+
}
193197
}
194-
195-
return new JpegFileMarker((byte)m, stream.Position - 2);
196198
}
197-
198-
return new JpegFileMarker(marker[1], stream.Position - 2, true);
199199
}
200200

201201
/// <inheritdoc/>
@@ -331,15 +331,12 @@ internal void ParseStream(BufferedReadStream stream, SpectralConverter spectralC
331331
JpegThrowHelper.ThrowInvalidImageContentException("Missing SOI marker.");
332332
}
333333

334-
stream.Read(this.markerBuffer, 0, 2);
335-
byte marker = this.markerBuffer[1];
336-
fileMarker = new JpegFileMarker(marker, (int)stream.Position - 2);
334+
fileMarker = FindNextFileMarker(stream);
337335
this.QuantizationTables ??= new Block8x8F[4];
338336

339337
// Break only when we discover a valid EOI marker.
340338
// https://github.com/SixLabors/ImageSharp/issues/695
341-
while (fileMarker.Marker != JpegConstants.Markers.EOI
342-
|| (fileMarker.Marker == JpegConstants.Markers.EOI && fileMarker.Invalid))
339+
while (fileMarker.Marker != JpegConstants.Markers.EOI)
343340
{
344341
cancellationToken.ThrowIfCancellationRequested();
345342

@@ -491,7 +488,7 @@ internal void ParseStream(BufferedReadStream stream, SpectralConverter spectralC
491488
}
492489

493490
// Read on.
494-
fileMarker = FindNextFileMarker(this.markerBuffer, stream);
491+
fileMarker = FindNextFileMarker(stream);
495492
}
496493
}
497494

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public void Issue2057_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
220220

221221
// https://github.com/SixLabors/ImageSharp/issues/2133
222222
[Theory]
223-
[WithFile(TestImages.Jpeg.Issues.Issue2133DeduceColorSpace, PixelTypes.Rgba32)]
223+
[WithFile(TestImages.Jpeg.Issues.Issue2133_DeduceColorSpace, PixelTypes.Rgba32)]
224224
public void Issue2133_DeduceColorSpace<TPixel>(TestImageProvider<TPixel> provider)
225225
where TPixel : unmanaged, IPixel<TPixel>
226226
{
@@ -231,6 +231,19 @@ public void Issue2133_DeduceColorSpace<TPixel>(TestImageProvider<TPixel> provide
231231
}
232232
}
233233

234+
// https://github.com/SixLabors/ImageSharp/issues/2133
235+
[Theory]
236+
[WithFile(TestImages.Jpeg.Issues.Issue2136_ScanMarkerExtraneousBytes, PixelTypes.Rgba32)]
237+
public void Issue2136_DecodeWorks<TPixel>(TestImageProvider<TPixel> provider)
238+
where TPixel : unmanaged, IPixel<TPixel>
239+
{
240+
using (Image<TPixel> image = provider.GetImage(JpegDecoder))
241+
{
242+
image.DebugSave(provider);
243+
image.CompareToOriginal(provider);
244+
}
245+
}
246+
234247
// DEBUG ONLY!
235248
// The PDF.js output should be saved by "tests\ImageSharp.Tests\Formats\Jpg\pdfjs\jpeg-converter.htm"
236249
// into "\tests\Images\ActualOutput\JpegDecoderTests\"

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ public static class Issues
272272
public const string Issue2057App1Parsing = "Jpg/issues/Issue2057-App1Parsing.jpg";
273273
public const string ExifNullArrayTag = "Jpg/issues/issue-2056-exif-null-array.jpg";
274274
public const string ValidExifArgumentNullExceptionOnEncode = "Jpg/issues/Issue2087-exif-null-reference-on-encode.jpg";
275-
public const string Issue2133DeduceColorSpace = "Jpg/issues/Issue2133.jpg";
275+
public const string Issue2133_DeduceColorSpace = "Jpg/issues/Issue2133.jpg";
276+
public const string Issue2136_ScanMarkerExtraneousBytes = "Jpg/issues/Issue2136-scan-segment-extraneous-bytes.jpg";
276277

277278
public static class Fuzz
278279
{
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)