mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 18:56:17 +03:00
Merge pull request #5372 from wiredfool/tiff-crash-fixes
Fix recent Tiff crashes in TiffDecode.c
This commit is contained in:
commit
60dbc10cee
BIN
Tests/images/crash-0da013a13571cc8eb457a39fee8db18f8a3c7127.tif
Normal file
BIN
Tests/images/crash-0da013a13571cc8eb457a39fee8db18f8a3c7127.tif
Normal file
Binary file not shown.
BIN
Tests/images/crash-74d2a78403a5a59db1fb0a2b8735ac068a75f6e3.tif
Normal file
BIN
Tests/images/crash-74d2a78403a5a59db1fb0a2b8735ac068a75f6e3.tif
Normal file
Binary file not shown.
BIN
Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif
Normal file
BIN
Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif
Normal file
Binary file not shown.
|
@ -33,6 +33,9 @@ from .helper import on_ci
|
||||||
"Tests/images/crash-86214e58da443d2b80820cff9677a38a33dcbbca.tif",
|
"Tests/images/crash-86214e58da443d2b80820cff9677a38a33dcbbca.tif",
|
||||||
"Tests/images/crash-f46f5b2f43c370fe65706c11449f567ecc345e74.tif",
|
"Tests/images/crash-f46f5b2f43c370fe65706c11449f567ecc345e74.tif",
|
||||||
"Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif",
|
"Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif",
|
||||||
|
"Tests/images/crash-74d2a78403a5a59db1fb0a2b8735ac068a75f6e3.tif",
|
||||||
|
"Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif",
|
||||||
|
"Tests/images/crash-0da013a13571cc8eb457a39fee8db18f8a3c7127.tif",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")
|
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")
|
||||||
|
|
|
@ -1250,6 +1250,10 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if bps_count > len(bps_tuple) and len(bps_tuple) == 1:
|
if bps_count > len(bps_tuple) and len(bps_tuple) == 1:
|
||||||
bps_tuple = bps_tuple * bps_count
|
bps_tuple = bps_tuple * bps_count
|
||||||
|
|
||||||
|
samplesPerPixel = self.tag_v2.get(SAMPLESPERPIXEL, 1)
|
||||||
|
if len(bps_tuple) != samplesPerPixel:
|
||||||
|
raise SyntaxError("unknown data organization")
|
||||||
|
|
||||||
# mode: check photometric interpretation and bits per pixel
|
# mode: check photometric interpretation and bits per pixel
|
||||||
key = (
|
key = (
|
||||||
self.tag_v2.prefix,
|
self.tag_v2.prefix,
|
||||||
|
|
|
@ -265,7 +265,7 @@ _decodeAsRGBA(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
ret = TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_block);
|
ret = TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 1) {
|
if (ret != 1 || rows_per_block==(UINT32)(-1)) {
|
||||||
rows_per_block = state->ysize;
|
rows_per_block = state->ysize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,17 +281,6 @@ _decodeAsRGBA(Imaging im, ImagingCodecState state, TIFF *tiff) {
|
||||||
img.req_orientation = ORIENTATION_TOPLEFT;
|
img.req_orientation = ORIENTATION_TOPLEFT;
|
||||||
img.col_offset = 0;
|
img.col_offset = 0;
|
||||||
|
|
||||||
if (state->xsize != img.width || state->ysize != img.height) {
|
|
||||||
TRACE(
|
|
||||||
("Inconsistent Image Error: %d =? %d, %d =? %d",
|
|
||||||
state->xsize,
|
|
||||||
img.width,
|
|
||||||
state->ysize,
|
|
||||||
img.height));
|
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
|
||||||
goto decodergba_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* overflow check for row byte size */
|
/* overflow check for row byte size */
|
||||||
if (INT_MAX / 4 < img.width) {
|
if (INT_MAX / 4 < img.width) {
|
||||||
state->errcode = IMAGING_CODEC_MEMORY;
|
state->errcode = IMAGING_CODEC_MEMORY;
|
||||||
|
@ -462,7 +451,7 @@ _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff, int planes, Imagin
|
||||||
UINT8 *new_data;
|
UINT8 *new_data;
|
||||||
UINT32 rows_per_strip;
|
UINT32 rows_per_strip;
|
||||||
int ret;
|
int ret;
|
||||||
tsize_t strip_size, row_byte_size;
|
tsize_t strip_size, row_byte_size, unpacker_row_byte_size;
|
||||||
|
|
||||||
ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
|
ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
|
||||||
if (ret != 1 || rows_per_strip==(UINT32)(-1)) {
|
if (ret != 1 || rows_per_strip==(UINT32)(-1)) {
|
||||||
|
@ -482,7 +471,8 @@ _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff, int planes, Imagin
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strip_size > ((state->xsize * state->bits / planes + 7) / 8) * rows_per_strip) {
|
unpacker_row_byte_size = (state->xsize * state->bits / planes + 7) / 8;
|
||||||
|
if (strip_size > (unpacker_row_byte_size * rows_per_strip)) {
|
||||||
// If the strip size as expected by LibTiff isn't what we're expecting, abort.
|
// If the strip size as expected by LibTiff isn't what we're expecting, abort.
|
||||||
// man: TIFFStripSize returns the equivalent size for a strip of data as it would be returned in a
|
// man: TIFFStripSize returns the equivalent size for a strip of data as it would be returned in a
|
||||||
// call to TIFFReadEncodedStrip ...
|
// call to TIFFReadEncodedStrip ...
|
||||||
|
@ -496,7 +486,9 @@ _decodeStrip(Imaging im, ImagingCodecState state, TIFF *tiff, int planes, Imagin
|
||||||
|
|
||||||
row_byte_size = TIFFScanlineSize(tiff);
|
row_byte_size = TIFFScanlineSize(tiff);
|
||||||
|
|
||||||
if (row_byte_size == 0 || row_byte_size > strip_size) {
|
// if the unpacker calculated row size is > row byte size, (at least) the last
|
||||||
|
// row of the strip will have a read buffer overflow.
|
||||||
|
if (row_byte_size == 0 || unpacker_row_byte_size > row_byte_size) {
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -559,6 +551,7 @@ ImagingLibTiffDecode(
|
||||||
uint16 planarconfig = 0;
|
uint16 planarconfig = 0;
|
||||||
int planes = 1;
|
int planes = 1;
|
||||||
ImagingShuffler unpackers[4];
|
ImagingShuffler unpackers[4];
|
||||||
|
UINT32 img_width, img_height;
|
||||||
|
|
||||||
memset(unpackers, 0, sizeof(ImagingShuffler) * 4);
|
memset(unpackers, 0, sizeof(ImagingShuffler) * 4);
|
||||||
|
|
||||||
|
@ -655,6 +648,20 @@ ImagingLibTiffDecode(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width);
|
||||||
|
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height);
|
||||||
|
|
||||||
|
if (state->xsize != img_width || state->ysize != img_height) {
|
||||||
|
TRACE(
|
||||||
|
("Inconsistent Image Error: %d =? %d, %d =? %d",
|
||||||
|
state->xsize,
|
||||||
|
img_width,
|
||||||
|
state->ysize,
|
||||||
|
img_height));
|
||||||
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
|
goto decode_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
|
TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);
|
||||||
TIFFGetField(tiff, TIFFTAG_COMPRESSION, &compression);
|
TIFFGetField(tiff, TIFFTAG_COMPRESSION, &compression);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user