In l_ldap_str2dn(), after rdnlist is appended to the parent list tmp, the local variable still holds its own reference. If a later PyList_Append(rdnlist, tuple) fails, the function jumps to failed without releasing that local reference, leaking one list per failure.
File: Modules/functions.c
Function: l_ldap_str2dn
Relevant code:
rdnlist = PyList_New(0);
if (!rdnlist)
goto failed;
if (PyList_Append(tmp, rdnlist) == -1) { /* on success, refcount is now 2 */
Py_DECREF(rdnlist);
goto failed;
}
for (j = 0; rdn[j]; j++) {
...
tuple = Py_BuildValue(...);
if (!tuple) {
Py_DECREF(rdnlist); /* this branch releases the local ref */
goto failed;
}
if (PyList_Append(rdnlist, tuple) == -1) {
Py_DECREF(tuple);
goto failed; /* BUG: local `rdnlist` ref not released */
}
Py_DECREF(tuple);
}
Py_DECREF(rdnlist); /* normal path releases the local ref */
After PyList_Append(tmp, rdnlist) succeeds, rdnlist has refcount 2 (the parent list tmp plus the local). The failed: label only does
Py_XDECREF(tmp), which drops the parent's reference; the extra local reference survives, so rdnlist leaks. The sibling !tuple branch already does Py_DECREF(rdnlist) before goto failed, which is exactly the missing step in the append-failure branch.
Suggested fix:
if (PyList_Append(rdnlist, tuple) == -1) {
Py_DECREF(tuple);
Py_DECREF(rdnlist);
goto failed;
}
In
l_ldap_str2dn(), afterrdnlistis appended to the parent listtmp, the local variable still holds its own reference. If a laterPyList_Append(rdnlist, tuple)fails, the function jumps tofailedwithout releasing that local reference, leaking one list per failure.File:
Modules/functions.cFunction:
l_ldap_str2dnRelevant code:
After
PyList_Append(tmp, rdnlist)succeeds,rdnlisthas refcount 2 (the parent listtmpplus the local). Thefailed:label only doesPy_XDECREF(tmp), which drops the parent's reference; the extra local reference survives, sordnlistleaks. The sibling!tuplebranch already doesPy_DECREF(rdnlist)beforegoto failed, which is exactly the missing step in the append-failure branch.Suggested fix: