Skip to content

Commit

Permalink
Merge pull request #8063 from radarhere/possible_formats
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed Jun 28, 2024
2 parents 02133dc + 3308a05 commit 3fdaecb
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
9 changes: 9 additions & 0 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ def test_open_formats(self) -> None:
assert im.mode == "RGB"
assert im.size == (128, 128)

def test_open_verbose_failure(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(Image, "WARN_POSSIBLE_FORMATS", True)

im = io.BytesIO(b"")
with pytest.warns(UserWarning):
with pytest.raises(UnidentifiedImageError):
with Image.open(im):
pass

def test_width_height(self) -> None:
im = Image.new("RGB", (1, 2))
assert im.width == 1
Expand Down
5 changes: 5 additions & 0 deletions docs/reference/Image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ Constants
Set to 89,478,485, approximately 0.25GB for a 24-bit (3 bpp) image.
See :py:meth:`~PIL.Image.open` for more information about how this is used.

.. data:: WARN_POSSIBLE_FORMATS

Set to false. If true, when an image cannot be identified, warnings will be raised
from formats that attempted to read the data.

Transpose methods
^^^^^^^^^^^^^^^^^

Expand Down
16 changes: 8 additions & 8 deletions src/PIL/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class DecompressionBombError(Exception):
pass


WARN_POSSIBLE_FORMATS: bool = False

# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image
MAX_IMAGE_PIXELS: int | None = int(1024 * 1024 * 1024 // 4 // 3)

Expand Down Expand Up @@ -3441,7 +3443,7 @@ def open(

preinit()

accept_warnings: list[str] = []
warning_messages: list[str] = []

def _open_core(
fp: IO[bytes],
Expand All @@ -3457,17 +3459,15 @@ def _open_core(
factory, accept = OPEN[i]
result = not accept or accept(prefix)
if isinstance(result, str):
accept_warnings.append(result)
warning_messages.append(result)
elif result:
fp.seek(0)
im = factory(fp, filename)
_decompression_bomb_check(im.size)
return im
except (SyntaxError, IndexError, TypeError, struct.error):
# Leave disabled by default, spams the logs with image
# opening failures that are entirely expected.
# logger.debug("", exc_info=True)
continue
except (SyntaxError, IndexError, TypeError, struct.error) as e:
if WARN_POSSIBLE_FORMATS:
warning_messages.append(i + " opening failed. " + str(e))
except BaseException:
if exclusive_fp:
fp.close()
Expand All @@ -3492,7 +3492,7 @@ def _open_core(

if exclusive_fp:
fp.close()
for message in accept_warnings:
for message in warning_messages:
warnings.warn(message)
msg = "cannot identify image file %r" % (filename if filename else fp)
raise UnidentifiedImageError(msg)
Expand Down

0 comments on commit 3fdaecb

Please sign in to comment.