mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-30 23:47:27 +03:00 
			
		
		
		
	Use monkeypatch
This commit is contained in:
		
							parent
							
								
									cf7dd2f0e9
								
							
						
					
					
						commit
						8d835e8fc5
					
				|  | @ -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