The add_err macro used by LDAPinit_constants() returns -1 on several failure paths without releasing the exc exception object (and, on one path, nobj). These are import-time ownership bugs.
File: Modules/constants.c
Function: LDAPinit_constants (macro add_err)
Relevant code:
#define add_err(n) do { \
exc = PyErr_NewException("ldap." #n, LDAPexception_class, NULL); \
if (exc == NULL) return -1; \
nobj = PyLong_FromLong(LDAP_##n); \
if (nobj == NULL) return -1; \ /* leaks exc */
if (PyObject_SetAttrString(exc, "errnum", nobj) != 0) return -1; \ /* leaks exc and nobj */
Py_DECREF(nobj); \
errobjects[LDAP_##n+LDAP_ERROR_OFFSET] = exc; \
if (PyModule_AddObject(m, #n, exc) != 0) return -1; \ /* leaks exc */
Py_INCREF(exc); \
} while (0)
- If
PyLong_FromLong() fails, exc is leaked.
- If
PyObject_SetAttrString() fails, both exc and nobj are leaked.
- If
PyModule_AddObject() fails, exc is leaked (PyModule_AddObject only
steals the reference on success). Note errobjects[...] = exc stores a raw
pointer and does not own a reference.
Severity note: every one of these paths returns -1, which aborts module import, so the leaked objects have no lasting effect in practice — this is a correctness/hygiene issue on an import-abort path, not a runtime leak. Listed for completeness; lowest priority of the python-ldap findings.
Suggested fix: release owned references before returning, e.g. via a cleanup
label:
nobj = PyLong_FromLong(LDAP_##n); \
if (nobj == NULL) { Py_DECREF(exc); return -1; } \
if (PyObject_SetAttrString(exc, "errnum", nobj) != 0) { \
Py_DECREF(nobj); Py_DECREF(exc); return -1; \
} \
Py_DECREF(nobj); \
errobjects[LDAP_##n+LDAP_ERROR_OFFSET] = exc; \
if (PyModule_AddObject(m, #n, exc) != 0) { Py_DECREF(exc); return -1; } \
Py_INCREF(exc); \
The
add_errmacro used byLDAPinit_constants()returns-1on several failure paths without releasing theexcexception object (and, on one path,nobj). These are import-time ownership bugs.File:
Modules/constants.cFunction:
LDAPinit_constants(macroadd_err)Relevant code:
PyLong_FromLong()fails,excis leaked.PyObject_SetAttrString()fails, bothexcandnobjare leaked.PyModule_AddObject()fails,excis leaked (PyModule_AddObjectonlysteals the reference on success). Note
errobjects[...] = excstores a rawpointer and does not own a reference.
Severity note: every one of these paths returns
-1, which aborts module import, so the leaked objects have no lasting effect in practice — this is a correctness/hygiene issue on an import-abort path, not a runtime leak. Listed for completeness; lowest priority of the python-ldap findings.Suggested fix: release owned references before returning, e.g. via a cleanup
label: