Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Python errors when saving a (0, 0) TIFF image #5750

Merged
merged 1 commit into from Oct 13, 2021

Conversation

radarhere
Copy link
Member

At the moment, saving a zero by zero image to TIFF gives a ZeroDivisionError.

>>> from PIL import Image
>>> Image.new("RGB", (0, 0)).save("out.tiff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "PIL/Image.py", line 2235, in save
    save_handler(self, fp, filename)
  File "PIL/TiffImagePlugin.py", line 1586, in _save
    strips_per_image = (im.size[1] + rows_per_strip - 1) // rows_per_strip
ZeroDivisionError: integer division or modulo by zero

This PR ensures that rows_per_strip, and then later strip_byte_counts, are not zero, allowing the code to progress forward to a SystemError instead.

>>> Image.new("RGB", (0, 0)).save("out.tiff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "PIL/Image.py", line 2240, in save
  File "PIL/TiffImagePlugin.py", line 1759, in _save
  File "PIL/ImageFile.py", line 531, in _save
SystemError: tile cannot extend outside image

@radarhere radarhere added the TIFF label Oct 9, 2021
@radarhere
Copy link
Member Author

cc @kmilos

strip_byte_counts = stride * rows_per_strip
if rows_per_strip == 0:
rows_per_strip = 1
strip_byte_counts = 1 if stride == 0 else stride * rows_per_strip
strips_per_image = (im.size[1] + rows_per_strip - 1) // rows_per_strip
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just handle the problematic division instead, is it not enough?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set rows_per_strip to 1 since I presume that setting ROWSPERSTRIP to zero is not ideal.

I set strip_byte_counts to 1 since it is used in range later, and can't be zero.

@kmilos
Copy link
Contributor

kmilos commented Oct 11, 2021

This was actually raising two different kinds of error in 8.1 and before: SystemError indeed if uncompressed (no libtiff), but a different

RuntimeError: Error setting from dictionary


_TIFFVSetField: out.tiff: Bad value 0 for "RowsPerStrip" tag.

when using libtiff...

So what's the behaviour you want, both raising the same SystemError now I guess?

@radarhere
Copy link
Member Author

I created this PR more just out of the thought that we shouldn't raise a ZeroDivisionError.

@kmilos
Copy link
Contributor

kmilos commented Oct 13, 2021

As a side effect I think it is better both Pillow and libtiff writers now throw the same SystemError for this corner case, so please feel free to merge as far as I'm concerned.

@hugovk hugovk merged commit b34430b into python-pillow:master Oct 13, 2021
@radarhere radarhere deleted the zero branch October 13, 2021 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants