mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-11 09:00:59 +03:00
Use monkeypatch (#8707)
Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
This commit is contained in:
parent
569b785371
commit
e19a1496c2
|
@ -3,26 +3,25 @@ from __future__ import annotations
|
|||
import zlib
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageFile, PngImagePlugin
|
||||
|
||||
TEST_FILE = "Tests/images/png_decompression_dos.png"
|
||||
|
||||
|
||||
def test_ignore_dos_text() -> None:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
def test_ignore_dos_text(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
|
||||
try:
|
||||
im = Image.open(TEST_FILE)
|
||||
with Image.open(TEST_FILE) as im:
|
||||
im.load()
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
assert isinstance(im, PngImagePlugin.PngImageFile)
|
||||
for s in im.text.values():
|
||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||
assert isinstance(im, PngImagePlugin.PngImageFile)
|
||||
for s in im.text.values():
|
||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||
|
||||
for s in im.info.values():
|
||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||
for s in im.info.values():
|
||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||
|
||||
|
||||
def test_dos_text() -> None:
|
||||
|
|
|
@ -12,19 +12,16 @@ ORIGINAL_LIMIT = Image.MAX_IMAGE_PIXELS
|
|||
|
||||
|
||||
class TestDecompressionBomb:
|
||||
def teardown_method(self) -> None:
|
||||
Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT
|
||||
|
||||
def test_no_warning_small_file(self) -> None:
|
||||
# Implicit assert: no warning.
|
||||
# A warning would cause a failure.
|
||||
with Image.open(TEST_FILE):
|
||||
pass
|
||||
|
||||
def test_no_warning_no_limit(self) -> None:
|
||||
def test_no_warning_no_limit(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Arrange
|
||||
# Turn limit off
|
||||
Image.MAX_IMAGE_PIXELS = None
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||
assert Image.MAX_IMAGE_PIXELS is None
|
||||
|
||||
# Act / Assert
|
||||
|
@ -33,18 +30,18 @@ class TestDecompressionBomb:
|
|||
with Image.open(TEST_FILE):
|
||||
pass
|
||||
|
||||
def test_warning(self) -> None:
|
||||
def test_warning(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Set limit to trigger warning on the test file
|
||||
Image.MAX_IMAGE_PIXELS = 128 * 128 - 1
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 128 * 128 - 1)
|
||||
assert Image.MAX_IMAGE_PIXELS == 128 * 128 - 1
|
||||
|
||||
with pytest.warns(Image.DecompressionBombWarning):
|
||||
with Image.open(TEST_FILE):
|
||||
pass
|
||||
|
||||
def test_exception(self) -> None:
|
||||
def test_exception(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Set limit to trigger exception on the test file
|
||||
Image.MAX_IMAGE_PIXELS = 64 * 128 - 1
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 64 * 128 - 1)
|
||||
assert Image.MAX_IMAGE_PIXELS == 64 * 128 - 1
|
||||
|
||||
with pytest.raises(Image.DecompressionBombError):
|
||||
|
@ -66,9 +63,9 @@ class TestDecompressionBomb:
|
|||
with pytest.raises(Image.DecompressionBombError):
|
||||
im.seek(1)
|
||||
|
||||
def test_exception_gif_zero_width(self) -> None:
|
||||
def test_exception_gif_zero_width(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Set limit to trigger exception on the test file
|
||||
Image.MAX_IMAGE_PIXELS = 4 * 64 * 128
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 4 * 64 * 128)
|
||||
assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128
|
||||
|
||||
with pytest.raises(Image.DecompressionBombError):
|
||||
|
|
|
@ -35,22 +35,19 @@ def test_sanity() -> None:
|
|||
assert im.is_animated
|
||||
|
||||
|
||||
def test_prefix_chunk() -> None:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
with Image.open(animated_test_file_with_prefix_chunk) as im:
|
||||
assert im.mode == "P"
|
||||
assert im.size == (320, 200)
|
||||
assert im.format == "FLI"
|
||||
assert im.info["duration"] == 171
|
||||
assert im.is_animated
|
||||
def test_prefix_chunk(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
with Image.open(animated_test_file_with_prefix_chunk) as im:
|
||||
assert im.mode == "P"
|
||||
assert im.size == (320, 200)
|
||||
assert im.format == "FLI"
|
||||
assert im.info["duration"] == 171
|
||||
assert im.is_animated
|
||||
|
||||
palette = im.getpalette()
|
||||
assert palette[3:6] == [255, 255, 255]
|
||||
assert palette[381:384] == [204, 204, 12]
|
||||
assert palette[765:] == [252, 0, 0]
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
palette = im.getpalette()
|
||||
assert palette[3:6] == [255, 255, 255]
|
||||
assert palette[381:384] == [204, 204, 12]
|
||||
assert palette[765:] == [252, 0, 0]
|
||||
|
||||
|
||||
@pytest.mark.skipif(is_pypy(), reason="Requires CPython")
|
||||
|
|
|
@ -109,7 +109,7 @@ def test_palette_not_needed_for_second_frame() -> None:
|
|||
assert_image_similar(im, hopper("L").convert("RGB"), 8)
|
||||
|
||||
|
||||
def test_strategy() -> None:
|
||||
def test_strategy(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/iss634.gif") as im:
|
||||
expected_rgb_always = im.convert("RGB")
|
||||
|
||||
|
@ -119,35 +119,36 @@ def test_strategy() -> None:
|
|||
im.seek(1)
|
||||
expected_different = im.convert("RGB")
|
||||
|
||||
try:
|
||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_ALWAYS
|
||||
with Image.open("Tests/images/iss634.gif") as im:
|
||||
assert im.mode == "RGB"
|
||||
assert_image_equal(im, expected_rgb_always)
|
||||
monkeypatch.setattr(
|
||||
GifImagePlugin, "LOADING_STRATEGY", GifImagePlugin.LoadingStrategy.RGB_ALWAYS
|
||||
)
|
||||
with Image.open("Tests/images/iss634.gif") as im:
|
||||
assert im.mode == "RGB"
|
||||
assert_image_equal(im, expected_rgb_always)
|
||||
|
||||
with Image.open("Tests/images/chi.gif") as im:
|
||||
assert im.mode == "RGBA"
|
||||
assert_image_equal(im, expected_rgb_always_rgba)
|
||||
with Image.open("Tests/images/chi.gif") as im:
|
||||
assert im.mode == "RGBA"
|
||||
assert_image_equal(im, expected_rgb_always_rgba)
|
||||
|
||||
GifImagePlugin.LOADING_STRATEGY = (
|
||||
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
|
||||
)
|
||||
# Stay in P mode with only a global palette
|
||||
with Image.open("Tests/images/chi.gif") as im:
|
||||
assert im.mode == "P"
|
||||
monkeypatch.setattr(
|
||||
GifImagePlugin,
|
||||
"LOADING_STRATEGY",
|
||||
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY,
|
||||
)
|
||||
# Stay in P mode with only a global palette
|
||||
with Image.open("Tests/images/chi.gif") as im:
|
||||
assert im.mode == "P"
|
||||
|
||||
im.seek(1)
|
||||
assert im.mode == "P"
|
||||
assert_image_equal(im.convert("RGB"), expected_different)
|
||||
im.seek(1)
|
||||
assert im.mode == "P"
|
||||
assert_image_equal(im.convert("RGB"), expected_different)
|
||||
|
||||
# Change to RGB mode when a frame has an individual palette
|
||||
with Image.open("Tests/images/iss634.gif") as im:
|
||||
assert im.mode == "P"
|
||||
# Change to RGB mode when a frame has an individual palette
|
||||
with Image.open("Tests/images/iss634.gif") as im:
|
||||
assert im.mode == "P"
|
||||
|
||||
im.seek(1)
|
||||
assert im.mode == "RGB"
|
||||
finally:
|
||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
||||
im.seek(1)
|
||||
assert im.mode == "RGB"
|
||||
|
||||
|
||||
def test_optimize() -> None:
|
||||
|
@ -555,17 +556,15 @@ def test_dispose_background_transparency() -> None:
|
|||
def test_transparent_dispose(
|
||||
loading_strategy: GifImagePlugin.LoadingStrategy,
|
||||
expected_colors: tuple[tuple[int | tuple[int, int, int, int], ...]],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
GifImagePlugin.LOADING_STRATEGY = loading_strategy
|
||||
try:
|
||||
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
||||
for frame in range(3):
|
||||
img.seek(frame)
|
||||
for x in range(3):
|
||||
color = img.getpixel((x, 0))
|
||||
assert color == expected_colors[frame][x]
|
||||
finally:
|
||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
||||
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
|
||||
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
||||
for frame in range(3):
|
||||
img.seek(frame)
|
||||
for x in range(3):
|
||||
color = img.getpixel((x, 0))
|
||||
assert color == expected_colors[frame][x]
|
||||
|
||||
|
||||
def test_dispose_previous() -> None:
|
||||
|
@ -1398,24 +1397,23 @@ def test_lzw_bits() -> None:
|
|||
),
|
||||
)
|
||||
def test_extents(
|
||||
test_file: str, loading_strategy: GifImagePlugin.LoadingStrategy
|
||||
test_file: str,
|
||||
loading_strategy: GifImagePlugin.LoadingStrategy,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
GifImagePlugin.LOADING_STRATEGY = loading_strategy
|
||||
try:
|
||||
with Image.open("Tests/images/" + test_file) as im:
|
||||
assert im.size == (100, 100)
|
||||
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
|
||||
with Image.open("Tests/images/" + test_file) as im:
|
||||
assert im.size == (100, 100)
|
||||
|
||||
# Check that n_frames does not change the size
|
||||
assert im.n_frames == 2
|
||||
assert im.size == (100, 100)
|
||||
# Check that n_frames does not change the size
|
||||
assert im.n_frames == 2
|
||||
assert im.size == (100, 100)
|
||||
|
||||
im.seek(1)
|
||||
assert im.size == (150, 150)
|
||||
im.seek(1)
|
||||
assert im.size == (150, 150)
|
||||
|
||||
im.load()
|
||||
assert im.im.size == (150, 150)
|
||||
finally:
|
||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
||||
im.load()
|
||||
assert im.im.size == (150, 150)
|
||||
|
||||
|
||||
def test_missing_background() -> None:
|
||||
|
|
|
@ -243,26 +243,23 @@ def test_draw_reloaded(tmp_path: Path) -> None:
|
|||
assert_image_equal_tofile(im, "Tests/images/hopper_draw.ico")
|
||||
|
||||
|
||||
def test_truncated_mask() -> None:
|
||||
def test_truncated_mask(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# 1 bpp
|
||||
with open("Tests/images/hopper_mask.ico", "rb") as fp:
|
||||
data = fp.read()
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
data = data[:-3]
|
||||
|
||||
try:
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
assert im.mode == "1"
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
assert im.mode == "1"
|
||||
|
||||
# 32 bpp
|
||||
output = io.BytesIO()
|
||||
expected = hopper("RGBA")
|
||||
expected.save(output, "ico", bitmap_format="bmp")
|
||||
# 32 bpp
|
||||
output = io.BytesIO()
|
||||
expected = hopper("RGBA")
|
||||
expected.save(output, "ico", bitmap_format="bmp")
|
||||
|
||||
data = output.getvalue()[:-1]
|
||||
data = output.getvalue()[:-1]
|
||||
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
assert im.mode == "RGB"
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
with Image.open(io.BytesIO(data)) as im:
|
||||
assert im.mode == "RGB"
|
||||
|
|
|
@ -530,12 +530,13 @@ class TestFileJpeg:
|
|||
@mark_if_feature_version(
|
||||
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
||||
)
|
||||
def test_truncated_jpeg_should_read_all_the_data(self) -> None:
|
||||
def test_truncated_jpeg_should_read_all_the_data(
|
||||
self, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
filename = "Tests/images/truncated_jpeg.jpg"
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
with Image.open(filename) as im:
|
||||
im.load()
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
assert im.getbbox() is not None
|
||||
|
||||
def test_truncated_jpeg_throws_oserror(self) -> None:
|
||||
|
@ -1024,7 +1025,7 @@ class TestFileJpeg:
|
|||
im.save(f, xmp=b"1" * 65505)
|
||||
|
||||
@pytest.mark.timeout(timeout=1)
|
||||
def test_eof(self) -> None:
|
||||
def test_eof(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Even though this decoder never says that it is finished
|
||||
# the image should still end when there is no new data
|
||||
class InfiniteMockPyDecoder(ImageFile.PyDecoder):
|
||||
|
@ -1039,9 +1040,8 @@ class TestFileJpeg:
|
|||
im.tile = [
|
||||
ImageFile._Tile("INFINITE", (0, 0, 128, 128), 0, ("RGB", 0, 1)),
|
||||
]
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
im.load()
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
def test_separate_tables(self) -> None:
|
||||
im = hopper()
|
||||
|
|
|
@ -181,14 +181,11 @@ def test_load_dpi() -> None:
|
|||
assert "dpi" not in im.info
|
||||
|
||||
|
||||
def test_restricted_icc_profile() -> None:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
# JPEG2000 image with a restricted ICC profile and a known colorspace
|
||||
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
|
||||
assert im.mode == "RGB"
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
def test_restricted_icc_profile(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
# JPEG2000 image with a restricted ICC profile and a known colorspace
|
||||
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
|
||||
assert im.mode == "RGB"
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
@ -1156,23 +1156,22 @@ class TestFileLibTiff(LibTiffTestCase):
|
|||
assert len(im.tag_v2[STRIPOFFSETS]) > 1
|
||||
|
||||
@pytest.mark.parametrize("argument", (True, False))
|
||||
def test_save_single_strip(self, argument: bool, tmp_path: Path) -> None:
|
||||
def test_save_single_strip(
|
||||
self, argument: bool, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
im = hopper("RGB").resize((256, 256))
|
||||
out = str(tmp_path / "temp.tif")
|
||||
|
||||
if not argument:
|
||||
TiffImagePlugin.STRIP_SIZE = 2**18
|
||||
try:
|
||||
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
|
||||
if argument:
|
||||
arguments["strip_size"] = 2**18
|
||||
im.save(out, "TIFF", **arguments)
|
||||
monkeypatch.setattr(TiffImagePlugin, "STRIP_SIZE", 2**18)
|
||||
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
|
||||
if argument:
|
||||
arguments["strip_size"] = 2**18
|
||||
im.save(out, "TIFF", **arguments)
|
||||
|
||||
with Image.open(out) as im:
|
||||
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||
assert len(im.tag_v2[STRIPOFFSETS]) == 1
|
||||
finally:
|
||||
TiffImagePlugin.STRIP_SIZE = 65536
|
||||
with Image.open(out) as im:
|
||||
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||
assert len(im.tag_v2[STRIPOFFSETS]) == 1
|
||||
|
||||
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", None))
|
||||
def test_save_zero(self, compression: str | None, tmp_path: Path) -> None:
|
||||
|
|
|
@ -363,7 +363,7 @@ class TestFilePng:
|
|||
with pytest.raises((OSError, SyntaxError)):
|
||||
im.verify()
|
||||
|
||||
def test_verify_ignores_crc_error(self) -> None:
|
||||
def test_verify_ignores_crc_error(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# check ignores crc errors in ancillary chunks
|
||||
|
||||
chunk_data = chunk(b"tEXt", b"spam")
|
||||
|
@ -373,24 +373,20 @@ class TestFilePng:
|
|||
with pytest.raises(SyntaxError):
|
||||
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
im = load(image_data)
|
||||
assert im is not None
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
im = load(image_data)
|
||||
assert im is not None
|
||||
|
||||
def test_verify_not_ignores_crc_error_in_required_chunk(self) -> None:
|
||||
def test_verify_not_ignores_crc_error_in_required_chunk(
|
||||
self, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
# check does not ignore crc errors in required chunks
|
||||
|
||||
image_data = MAGIC + IHDR[:-1] + b"q" + TAIL
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
with pytest.raises(SyntaxError):
|
||||
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
with pytest.raises(SyntaxError):
|
||||
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
||||
|
||||
def test_roundtrip_dpi(self) -> None:
|
||||
# Check dpi roundtripping
|
||||
|
@ -600,7 +596,7 @@ class TestFilePng:
|
|||
(b"prIV", b"VALUE3", True),
|
||||
]
|
||||
|
||||
def test_textual_chunks_after_idat(self) -> None:
|
||||
def test_textual_chunks_after_idat(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/hopper.png") as im:
|
||||
assert "comment" in im.text
|
||||
for k, v in {
|
||||
|
@ -614,18 +610,17 @@ class TestFilePng:
|
|||
with pytest.raises(OSError):
|
||||
assert isinstance(im.text, dict)
|
||||
|
||||
# Raises an EOFError in load_end
|
||||
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
||||
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
||||
|
||||
# Raises a UnicodeDecodeError in load_end
|
||||
with Image.open("Tests/images/truncated_image.png") as im:
|
||||
# The file is truncated
|
||||
with pytest.raises(OSError):
|
||||
im.text
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
assert isinstance(im.text, dict)
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
# Raises an EOFError in load_end
|
||||
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
||||
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
||||
|
||||
def test_unknown_compression_method(self) -> None:
|
||||
with pytest.raises(SyntaxError, match="Unknown compression method"):
|
||||
|
@ -651,15 +646,16 @@ class TestFilePng:
|
|||
@pytest.mark.parametrize(
|
||||
"cid", (b"IHDR", b"sRGB", b"pHYs", b"acTL", b"fcTL", b"fdAT")
|
||||
)
|
||||
def test_truncated_chunks(self, cid: bytes) -> None:
|
||||
def test_truncated_chunks(
|
||||
self, cid: bytes, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
fp = BytesIO()
|
||||
with PngImagePlugin.PngStream(fp) as png:
|
||||
with pytest.raises(ValueError):
|
||||
png.call(cid, 0, 0)
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
png.call(cid, 0, 0)
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
@pytest.mark.parametrize("save_all", (True, False))
|
||||
def test_specify_bits(self, save_all: bool, tmp_path: Path) -> None:
|
||||
|
@ -789,17 +785,14 @@ class TestFilePng:
|
|||
with Image.open(mystdout) as reloaded:
|
||||
assert_image_equal_tofile(reloaded, TEST_PNG_FILE)
|
||||
|
||||
def test_truncated_end_chunk(self) -> None:
|
||||
def test_truncated_end_chunk(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
||||
with pytest.raises(OSError):
|
||||
im.load()
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
||||
assert_image_equal_tofile(im, "Tests/images/hopper.png")
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
||||
assert_image_equal_tofile(im, "Tests/images/hopper.png")
|
||||
|
||||
|
||||
@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
|
||||
|
@ -808,11 +801,11 @@ class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
|||
mem_limit = 2 * 1024 # max increase in K
|
||||
iterations = 100 # Leak is 56k/iteration, this will leak 5.6megs
|
||||
|
||||
def test_leak_load(self) -> None:
|
||||
def test_leak_load(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with open("Tests/images/hopper.png", "rb") as f:
|
||||
DATA = BytesIO(f.read(16 * 1024))
|
||||
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
with Image.open(DATA) as im:
|
||||
im.load()
|
||||
|
||||
|
@ -820,7 +813,4 @@ class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
|||
with Image.open(DATA) as im:
|
||||
im.load()
|
||||
|
||||
try:
|
||||
self._test_leak(core)
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
self._test_leak(core)
|
||||
|
|
|
@ -939,11 +939,10 @@ class TestFileTiff:
|
|||
|
||||
@pytest.mark.timeout(6)
|
||||
@pytest.mark.filterwarnings("ignore:Truncated File Read")
|
||||
def test_timeout(self) -> None:
|
||||
def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/timeout-6646305047838720") as im:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
im.load()
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_file",
|
||||
|
|
|
@ -28,9 +28,9 @@ except ImportError:
|
|||
|
||||
|
||||
class TestUnsupportedWebp:
|
||||
def test_unsupported(self) -> None:
|
||||
def test_unsupported(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
if HAVE_WEBP:
|
||||
WebPImagePlugin.SUPPORTED = False
|
||||
monkeypatch.setattr(WebPImagePlugin, "SUPPORTED", False)
|
||||
|
||||
file_path = "Tests/images/hopper.webp"
|
||||
with pytest.warns(UserWarning):
|
||||
|
@ -38,9 +38,6 @@ class TestUnsupportedWebp:
|
|||
with Image.open(file_path):
|
||||
pass
|
||||
|
||||
if HAVE_WEBP:
|
||||
WebPImagePlugin.SUPPORTED = True
|
||||
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
class TestFileWebp:
|
||||
|
|
|
@ -191,13 +191,10 @@ class TestImageFile:
|
|||
im.load()
|
||||
|
||||
@skip_unless_feature("zlib")
|
||||
def test_truncated_without_errors(self) -> None:
|
||||
def test_truncated_without_errors(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
with Image.open("Tests/images/truncated_image.png") as im:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
im.load()
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
im.load()
|
||||
|
||||
@skip_unless_feature("zlib")
|
||||
def test_broken_datastream_with_errors(self) -> None:
|
||||
|
@ -206,13 +203,12 @@ class TestImageFile:
|
|||
im.load()
|
||||
|
||||
@skip_unless_feature("zlib")
|
||||
def test_broken_datastream_without_errors(self) -> None:
|
||||
def test_broken_datastream_without_errors(
|
||||
self, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
with Image.open("Tests/images/broken_data_stream.png") as im:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
try:
|
||||
im.load()
|
||||
finally:
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||
im.load()
|
||||
|
||||
|
||||
class MockPyDecoder(ImageFile.PyDecoder):
|
||||
|
|
|
@ -7,36 +7,30 @@ import pytest
|
|||
from PIL import Image
|
||||
|
||||
|
||||
def test_overflow() -> None:
|
||||
def test_overflow(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# There is the potential to overflow comparisons in map.c
|
||||
# if there are > SIZE_MAX bytes in the image or if
|
||||
# the file encodes an offset that makes
|
||||
# (offset + size(bytes)) > SIZE_MAX
|
||||
|
||||
# Note that this image triggers the decompression bomb warning:
|
||||
max_pixels = Image.MAX_IMAGE_PIXELS
|
||||
Image.MAX_IMAGE_PIXELS = None
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||
|
||||
# This image hits the offset test.
|
||||
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
||||
with pytest.raises((ValueError, MemoryError, OSError)):
|
||||
im.load()
|
||||
|
||||
Image.MAX_IMAGE_PIXELS = max_pixels
|
||||
|
||||
|
||||
def test_tobytes() -> None:
|
||||
def test_tobytes(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Note that this image triggers the decompression bomb warning:
|
||||
max_pixels = Image.MAX_IMAGE_PIXELS
|
||||
Image.MAX_IMAGE_PIXELS = None
|
||||
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||
|
||||
# Previously raised an access violation on Windows
|
||||
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
||||
with pytest.raises((ValueError, MemoryError, OSError)):
|
||||
im.tobytes()
|
||||
|
||||
Image.MAX_IMAGE_PIXELS = max_pixels
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
|
||||
def test_ysize() -> None:
|
||||
|
|
Loading…
Reference in New Issue
Block a user