Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Tests/images/tiff_tiled_jpeg_oob_read.tif
Binary file not shown.
10 changes: 10 additions & 0 deletions Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,16 @@ def test_tiled_ycbcr_jpeg_2x2_sampling(self) -> None:
with Image.open(infile) as im:
assert_image_similar_tofile(im, "Tests/images/flower.jpg", 1.5)

def test_tiled_jpeg_oob_read(self) -> None:
# A tiled TIFF whose libtiff-decoded, JPEG-compressed tile storage
# (TIFFTileSize) is smaller than tile_length rows of the *unpacked*
# rawmode's bytes-per-pixel would require. Decoding must fail safely
# rather than let the row unpacker read past the tile buffer
infile = "Tests/images/tiff_tiled_jpeg_oob_read.tif"
with Image.open(infile) as im:
with pytest.raises(OSError):
im.load()

def test_strip_planar_rgb(self) -> None:
# gdal_translate -co TILED=no -co INTERLEAVE=BAND -co COMPRESS=LZW \
# tiff_strip_raw.tif tiff_strip_planar_lzw.tiff
Expand Down
3 changes: 2 additions & 1 deletion src/libImaging/TiffDecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ _decodeTile(
return -1;
}

if (tile_bytes_size > ((tile_length * state->bits / planes + 7) / 8) * tile_width) {
if (tile_bytes_size !=
((tile_length * state->bits / planes + 7) / 8) * tile_width) {
// If the tile size as expected by LibTiff isn't what we're expecting, abort.
// man: TIFFTileSize returns the equivalent size for a tile of data as it
// would be returned in a call to TIFFReadTile ...
Expand Down
Loading