Skip to content

qoi truncated index error #9812

Description

@nevercodecorrect

What did you do?

I opened a truncated QOI file. Pillow reads its 14-byte header as a 1x220 RGBA image, then reaches EOF while decoding the declared pixels.

What did you expect to happen?

The truncated/malformed image should be rejected with Pillow's standard image-decoding exception, for example, an OSError describing a truncated or broken data stream, as other decoders do when reporting a premature EOF.

What actually happened?

QoiDecoder.decode() reaches EOF and indexes the empty result of read(1), so an implementation-level IndexError escapes from Image.load():

QOI (1, 220) RGBA
Traceback (most recent call last):
  File "repro.py", line 10, in <module>
    im.load()
  File ".../PIL/ImageFile.py", line 382, in load
    err_code = decoder.decode(b"")[1]
  File ".../PIL/QoiImagePlugin.py", line 64, in decode
    byte = self.fd.read(1)[0]
IndexError: index out of range

self.fd.read(1) returns b"" at EOF and is indexed without a length check. The one-byte QOI_OP_LUMA read (second_byte = self.fd.read(1)[0]) and the QOI_OP_RGB / QOI_OP_RGBA payload reads (self.fd.read(3) / read(4)) have the same missing short-read handling and can leak similar errors on other truncated inputs.

Those exceptions become an uncaught exception, but not a vulnerability.

What are your OS, Python and Pillow versions?

  • OS: Ubuntu 22.04.5 LTS, x86_64
  • Python: 3.10.12
  • Pillow: 12.3.0
--------------------------------------------------------------------
Pillow 12.3.0
Python 3.10.12 (main, Jun 22 2026, 18:55:27) [GCC 11.4.0]
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 12.3.0
*** TKINTER support not installed
--- FREETYPE2 support ok, loaded 2.14.3
--- LITTLECMS2 support ok, loaded 2.19
--- WEBP support ok, loaded 1.6.0
--- AVIF support ok, loaded 1.4.2
--- JPEG support ok, compiled for libjpeg-turbo 3.1.4.1
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.4
--- ZLIB (PNG/ZIP) support ok, loaded 1.2.11, compiled for zlib-ng 2.3.3
--- LIBTIFF support ok, loaded 4.7.1
--- RAQM (Bidirectional Text) support ok, loaded 0.10.5, fribidi 1.0.8, harfbuzz 14.2.1
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------
import base64, io
from PIL import Image
data = base64.b64decode("cW9pZgAAAAEAAADc///T//QAAAEAAwAAAAABAA==")

im = Image.open(io.BytesIO(data))
print(im.format, im.size, im.mode)   # QOI (1, 220) RGBA
im.load()                            # IndexError: index out of range

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions