@@ -286,33 +286,36 @@ def decode(self, buffer):
286
286
raise OSError ("Truncated Blp file" ) from e
287
287
return 0 , 0
288
288
289
+ def _safe_read (self , length ):
290
+ return ImageFile ._safe_read (self .fd , length )
291
+
289
292
def _read_palette (self ):
290
293
ret = []
291
294
for i in range (256 ):
292
295
try :
293
- b , g , r , a = struct .unpack ("<4B" , self .fd . read (4 ))
296
+ b , g , r , a = struct .unpack ("<4B" , self ._safe_read (4 ))
294
297
except struct .error :
295
298
break
296
299
ret .append ((b , g , r , a ))
297
300
return ret
298
301
299
302
def _read_blp_header (self ):
300
- (self ._blp_compression ,) = struct .unpack ("<i" , self .fd . read (4 ))
303
+ (self ._blp_compression ,) = struct .unpack ("<i" , self ._safe_read (4 ))
301
304
302
- (self ._blp_encoding ,) = struct .unpack ("<b" , self .fd . read (1 ))
303
- (self ._blp_alpha_depth ,) = struct .unpack ("<b" , self .fd . read (1 ))
304
- (self ._blp_alpha_encoding ,) = struct .unpack ("<b" , self .fd . read (1 ))
305
- (self ._blp_mips ,) = struct .unpack ("<b" , self .fd . read (1 ))
305
+ (self ._blp_encoding ,) = struct .unpack ("<b" , self ._safe_read (1 ))
306
+ (self ._blp_alpha_depth ,) = struct .unpack ("<b" , self ._safe_read (1 ))
307
+ (self ._blp_alpha_encoding ,) = struct .unpack ("<b" , self ._safe_read (1 ))
308
+ (self ._blp_mips ,) = struct .unpack ("<b" , self ._safe_read (1 ))
306
309
307
- self .size = struct .unpack ("<II" , self .fd . read (8 ))
310
+ self .size = struct .unpack ("<II" , self ._safe_read (8 ))
308
311
309
312
if self .magic == b"BLP1" :
310
313
# Only present for BLP1
311
- (self ._blp_encoding ,) = struct .unpack ("<i" , self .fd . read (4 ))
312
- (self ._blp_subtype ,) = struct .unpack ("<i" , self .fd . read (4 ))
314
+ (self ._blp_encoding ,) = struct .unpack ("<i" , self ._safe_read (4 ))
315
+ (self ._blp_subtype ,) = struct .unpack ("<i" , self ._safe_read (4 ))
313
316
314
- self ._blp_offsets = struct .unpack ("<16I" , self .fd . read (16 * 4 ))
315
- self ._blp_lengths = struct .unpack ("<16I" , self .fd . read (16 * 4 ))
317
+ self ._blp_offsets = struct .unpack ("<16I" , self ._safe_read (16 * 4 ))
318
+ self ._blp_lengths = struct .unpack ("<16I" , self ._safe_read (16 * 4 ))
316
319
317
320
318
321
class BLP1Decoder (_BLPBaseDecoder ):
@@ -324,7 +327,7 @@ def _load(self):
324
327
if self ._blp_encoding in (4 , 5 ):
325
328
data = bytearray ()
326
329
palette = self ._read_palette ()
327
- _data = BytesIO (self .fd . read (self ._blp_lengths [0 ]))
330
+ _data = BytesIO (self ._safe_read (self ._blp_lengths [0 ]))
328
331
while True :
329
332
try :
330
333
(offset ,) = struct .unpack ("<B" , _data .read (1 ))
@@ -346,13 +349,14 @@ def _load(self):
346
349
def _decode_jpeg_stream (self ):
347
350
from PIL .JpegImagePlugin import JpegImageFile
348
351
349
- (jpeg_header_size ,) = struct .unpack ("<I" , self .fd . read (4 ))
350
- jpeg_header = self .fd . read (jpeg_header_size )
351
- self .fd . read (self ._blp_offsets [0 ] - self .fd .tell ()) # What IS this?
352
- data = self .fd . read (self ._blp_lengths [0 ])
352
+ (jpeg_header_size ,) = struct .unpack ("<I" , self ._safe_read (4 ))
353
+ jpeg_header = self ._safe_read (jpeg_header_size )
354
+ self ._safe_read (self ._blp_offsets [0 ] - self .fd .tell ()) # What IS this?
355
+ data = self ._safe_read (self ._blp_lengths [0 ])
353
356
data = jpeg_header + data
354
357
data = BytesIO (data )
355
358
image = JpegImageFile (data )
359
+ Image ._decompression_bomb_check (image .size )
356
360
self .tile = image .tile # :/
357
361
self .fd = image .fp
358
362
self .mode = image .mode
@@ -369,7 +373,7 @@ def _load(self):
369
373
# Uncompressed or DirectX compression
370
374
371
375
if self ._blp_encoding == BLP_ENCODING_UNCOMPRESSED :
372
- _data = BytesIO (self .fd . read (self ._blp_lengths [0 ]))
376
+ _data = BytesIO (self ._safe_read (self ._blp_lengths [0 ]))
373
377
while True :
374
378
try :
375
379
(offset ,) = struct .unpack ("<B" , _data .read (1 ))
@@ -383,20 +387,20 @@ def _load(self):
383
387
linesize = (self .size [0 ] + 3 ) // 4 * 8
384
388
for yb in range ((self .size [1 ] + 3 ) // 4 ):
385
389
for d in decode_dxt1 (
386
- self .fd . read (linesize ), alpha = bool (self ._blp_alpha_depth )
390
+ self ._safe_read (linesize ), alpha = bool (self ._blp_alpha_depth )
387
391
):
388
392
data += d
389
393
390
394
elif self ._blp_alpha_encoding == BLP_ALPHA_ENCODING_DXT3 :
391
395
linesize = (self .size [0 ] + 3 ) // 4 * 16
392
396
for yb in range ((self .size [1 ] + 3 ) // 4 ):
393
- for d in decode_dxt3 (self .fd . read (linesize )):
397
+ for d in decode_dxt3 (self ._safe_read (linesize )):
394
398
data += d
395
399
396
400
elif self ._blp_alpha_encoding == BLP_ALPHA_ENCODING_DXT5 :
397
401
linesize = (self .size [0 ] + 3 ) // 4 * 16
398
402
for yb in range ((self .size [1 ] + 3 ) // 4 ):
399
- for d in decode_dxt5 (self .fd . read (linesize )):
403
+ for d in decode_dxt5 (self ._safe_read (linesize )):
400
404
data += d
401
405
else :
402
406
raise BLPFormatError (
@@ -413,9 +417,11 @@ def _load(self):
413
417
self .set_as_raw (bytes (data ))
414
418
415
419
416
- Image .register_open (
417
- BlpImageFile .format , BlpImageFile , lambda p : p [:4 ] in (b"BLP1" , b"BLP2" )
418
- )
420
+ def _accept (prefix ):
421
+ return prefix [:4 ] in (b"BLP1" , b"BLP2" )
422
+
423
+
424
+ Image .register_open (BlpImageFile .format , BlpImageFile , _accept )
419
425
Image .register_extension (BlpImageFile .format , ".blp" )
420
426
421
427
Image .register_decoder ("BLP1" , BLP1Decoder )
0 commit comments