Bug Description
In src/encode.c, PyImaging_LibTiffEncoderNew calls PyDict_GetItemRef to look up each tag's type from the types dict. PyDict_GetItemRef returns a new reference, but the returned tag_type object is never released, leaking one reference per tag entry on every TIFF save that uses a types dict.
Location
src/encode.c:792–802
Code
PyObject *tag_type;
if (PyDict_GetItemRef(types, key, &tag_type) < 0) { ... }
if (tag_type) {
int type_int = PyLong_AsLong(tag_type);
if (type_int >= TIFF_BYTE && type_int <= TIFF_LONG8) {
type = (TIFFDataType)type_int;
}
// BUG: tag_type (NEW reference from PyDict_GetItemRef) is never Py_DECREF'd
}
PyDict_GetItemRef (unlike the deprecated PyDict_GetItem) always returns a new reference. The caller is responsible for releasing it. No Py_DECREF(tag_type) exists anywhere in this branch.
Impact
- One
PyLong object leaked per tag with a custom type entry, per TIFF save call
- In tight loops saving many TIFF files with custom tag types, this causes unbounded memory growth
- Severity: HIGH (leaks on every affected TIFF save)
Suggested Fix
Add Py_DECREF(tag_type); after the if (tag_type) block:
if (tag_type) {
int type_int = PyLong_AsLong(tag_type);
if (type_int >= TIFF_BYTE && type_int <= TIFF_LONG8) {
type = (TIFFDataType)type_int;
}
Py_DECREF(tag_type); // release the new reference
}
Environment
- Pillow version: current
main
- Affected: any
Image.save(..., format="TIFF") call that passes a tiffinfo dict with a types sub-dict
Bug Description
In
src/encode.c,PyImaging_LibTiffEncoderNewcallsPyDict_GetItemRefto look up each tag's type from thetypesdict.PyDict_GetItemRefreturns a new reference, but the returnedtag_typeobject is never released, leaking one reference per tag entry on every TIFF save that uses atypesdict.Location
src/encode.c:792–802Code
PyDict_GetItemRef(unlike the deprecatedPyDict_GetItem) always returns a new reference. The caller is responsible for releasing it. NoPy_DECREF(tag_type)exists anywhere in this branch.Impact
PyLongobject leaked per tag with a custom type entry, per TIFF save callSuggested Fix
Add
Py_DECREF(tag_type);after theif (tag_type)block:Environment
mainImage.save(..., format="TIFF")call that passes atiffinfodict with atypessub-dict