Skip to content

ImageOps.exif_transpose() raises struct.error on invalid EXIF rational #8965

Description

@epou

What did you do?

Attempted to process an image with ImageOps.exif_transpose(), which contains an EXIF tag with a value of (-1, 0).

What did you expect to happen?

The image should be processed without raising an error, with invalid EXIF values (like (-1, 0)) handled gracefully as float('nan') as a result of (1, 0).

What actually happened?

>>> from PIL import Image, ImageOps
>>> img = Image.open('/path/to/file.jpg')
>>> ImageOps.exif_transpose(img)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/ImageOps.py", line 712, in exif_transpose
    exif_image.info["exif"] = exif.tobytes()
                              ^^^^^^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/Image.py", line 4043, in tobytes
    return b"Exif\x00\x00" + head + ifd.tobytes(offset)
                                    ^^^^^^^^^^^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/TiffImagePlugin.py", line 983, in tobytes
    data = ifd.tobytes(offset)
           ^^^^^^^^^^^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/TiffImagePlugin.py", line 986, in tobytes
    data = self._write_dispatch[typ](self, *values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/TiffImagePlugin.py", line 841, in write_rational
    return b"".join(
           ^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/TiffImagePlugin.py", line 842, in <genexpr>
    self._pack("2L", *_limit_rational(frac, 2**32 - 1)) for frac in values
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/venv_pillow/lib/python3.12/site-packages/PIL/TiffImagePlugin.py", line 782, in _pack
    return struct.pack(self._endian + fmt, *values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: 'L' format requires 0 <= number <= 4294967295

What are your OS, Python and Pillow versions?

  • OS: Ubuntu 22.04
  • Python: 3.12.3
  • Pillow: 11.1.0
(venv_pillow)  user@thinkpad  ~  python3 -m PIL.report
--------------------------------------------------------------------
Pillow 11.1.0
Python 3.12.3 (main, Feb  4 2025, 14:48:35) [GCC 13.3.0]
--------------------------------------------------------------------
Python executable is /home/user/venv_pillow/bin/python3
Environment Python files loaded from /home/user/venv_pillow
System Python files loaded from /usr
--------------------------------------------------------------------
Python Pillow modules loaded from /home/user/venv_pillow/lib/python3.12/site-packages/PIL
Binary Pillow modules loaded from /home/user/venv_pillow/lib/python3.12/site-packages/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 11.1.0
--- TKINTER support ok, loaded 8.6
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.5.0
--- JPEG support ok, compiled for libjpeg-turbo 3.1.0
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.3
--- ZLIB (PNG/ZIP) support ok, loaded 1.3, compiled for zlib-ng 2.2.2
--- LIBTIFF support ok, loaded 4.6.0
--- RAQM (Bidirectional Text) support ok, loaded 0.10.1, fribidi 1.0.13, harfbuzz 10.1.0
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions