@@ -228,16 +228,17 @@ public void LoadTables(byte[] tableBytes, HuffmanScanDecoder huffmanScanDecoder)
228
228
this . Metadata = new ImageMetadata ( ) ;
229
229
this . QuantizationTables = new Block8x8F [ 4 ] ;
230
230
this . scanDecoder = huffmanScanDecoder ;
231
+
232
+ if ( tableBytes . Length < 4 )
233
+ {
234
+ JpegThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read marker" ) ;
235
+ }
236
+
231
237
using var ms = new MemoryStream ( tableBytes ) ;
232
238
using var stream = new BufferedReadStream ( this . Configuration , ms ) ;
233
239
234
240
// Check for the Start Of Image marker.
235
241
int bytesRead = stream . Read ( this . markerBuffer , 0 , 2 ) ;
236
- if ( bytesRead != 2 )
237
- {
238
- JpegThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read the SOI marker" ) ;
239
- }
240
-
241
242
var fileMarker = new JpegFileMarker ( this . markerBuffer [ 1 ] , 0 ) ;
242
243
if ( fileMarker . Marker != JpegConstants . Markers . SOI )
243
244
{
@@ -246,20 +247,22 @@ public void LoadTables(byte[] tableBytes, HuffmanScanDecoder huffmanScanDecoder)
246
247
247
248
// Read next marker.
248
249
bytesRead = stream . Read ( this . markerBuffer , 0 , 2 ) ;
249
- if ( bytesRead != 2 )
250
- {
251
- JpegThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read marker" ) ;
252
- }
253
-
254
- byte marker = this . markerBuffer [ 1 ] ;
255
- fileMarker = new JpegFileMarker ( marker , ( int ) stream . Position - 2 ) ;
250
+ fileMarker = new JpegFileMarker ( this . markerBuffer [ 1 ] , ( int ) stream . Position - 2 ) ;
256
251
257
252
while ( fileMarker . Marker != JpegConstants . Markers . EOI || ( fileMarker . Marker == JpegConstants . Markers . EOI && fileMarker . Invalid ) )
258
253
{
259
254
if ( ! fileMarker . Invalid )
260
255
{
261
256
// Get the marker length.
262
- int remaining = this . ReadUint16 ( stream ) - 2 ;
257
+ int markerContentByteSize = this . ReadUint16 ( stream ) - 2 ;
258
+
259
+ // Check whether stream actually has enought bytes to read
260
+ // markerContentByteSize is always positive so we cast
261
+ // to uint to avoid sign extension
262
+ if ( stream . RemainingBytes < ( uint ) markerContentByteSize )
263
+ {
264
+ JpegThrowHelper . ThrowNotEnoughBytesForMarker ( fileMarker . Marker ) ;
265
+ }
263
266
264
267
switch ( fileMarker . Marker )
265
268
{
@@ -269,13 +272,13 @@ public void LoadTables(byte[] tableBytes, HuffmanScanDecoder huffmanScanDecoder)
269
272
case JpegConstants . Markers . RST7 :
270
273
break ;
271
274
case JpegConstants . Markers . DHT :
272
- this . ProcessDefineHuffmanTablesMarker ( stream , remaining ) ;
275
+ this . ProcessDefineHuffmanTablesMarker ( stream , markerContentByteSize ) ;
273
276
break ;
274
277
case JpegConstants . Markers . DQT :
275
- this . ProcessDefineQuantizationTablesMarker ( stream , remaining ) ;
278
+ this . ProcessDefineQuantizationTablesMarker ( stream , markerContentByteSize ) ;
276
279
break ;
277
280
case JpegConstants . Markers . DRI :
278
- this . ProcessDefineRestartIntervalMarker ( stream , remaining ) ;
281
+ this . ProcessDefineRestartIntervalMarker ( stream , markerContentByteSize ) ;
279
282
break ;
280
283
case JpegConstants . Markers . EOI :
281
284
return ;
0 commit comments