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

[PNG] struct.error is raised when there is the broken IHDR chunk after the IDAT chunk #6252

Closed
ks888 opened this issue May 1, 2022 · 2 comments · Fixed by #6253
Closed

Comments

@ks888
Copy link

ks888 commented May 1, 2022

Hi, I am recently fuzzing this library and found the test case which raises struct.error.

What did you do?

from PIL import Image
import io

# assumes the current directory is the root of this repository.
with open('Tests/images/imagedraw_polygon_1px_high.png', 'rb') as f:
    data = bytearray(f.read())

# insert the IHDR chunk after the IDAT chunk. Its length, chunk type and crc are valid, but the IHDR chunk should contain more data.
data[61:61] = b"\x00\x00\x00\x00IHDR\xa8\xa1\xae\x0a"

# struct.error is raised
with Image.open(io.BytesIO(data)) as img:
    img.load()

What did you expect to happen?

Though the inserted IHDR chunk is broken, struct.error is a little confusing.

Maybe ValueError is better? Or the chunk may be ignored because other parts are still valid.
Another idea is to have verify() check the number of IHDR chunks. It should be 1 according to the png spec.

What actually happened?

Traceback (most recent call last):
  File "issue2.py", line 14, in <module>
    img.load()
  File "/usr/local/lib/python3.8/site-packages/PIL/ImageFile.py", line 256, in load
    self.load_end()
  File "/usr/local/lib/python3.8/site-packages/PIL/PngImagePlugin.py", line 942, in load_end
    self.png.call(cid, pos, length)
  File "/usr/local/lib/python3.8/site-packages/PIL/PngImagePlugin.py", line 187, in call
    return getattr(self, "chunk_" + cid.decode("ascii"))(pos, length)
  File "/usr/local/lib/python3.8/site-packages/PIL/PngImagePlugin.py", line 412, in chunk_IHDR
    self.im_size = i32(s, 0), i32(s, 4)
  File "/usr/local/lib/python3.8/site-packages/PIL/_binary.py", line 85, in i32be
    return unpack_from(">I", c, o)[0]
struct.error: unpack_from requires a buffer of at least 4 bytes for unpacking 4 bytes at offset 0 (actual buffer size is 0)

What are your OS, Python and Pillow versions?

  • OS: Debian GNU/Linux 11 (bullseye)
  • Python: 3.8.13
  • Pillow: 9.1.0
@radarhere radarhere changed the title [PNG] struct.error is raised when there is the broken IHDR chunk after the IDAT chunk. [PNG] struct.error is raised when there is the broken IHDR chunk after the IDAT chunk May 1, 2022
@radarhere
Copy link
Member

I've created PR #6253 to raise a ValueError for this situation.
Alternatively, if the user sets ImageFile.LOAD_TRUNCATED_IMAGES = True first, then no error will be raised.

@ks888
Copy link
Author

ks888 commented May 1, 2022

Wow. Thank you for the quick response and PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants