handle errors when constructing lists in the Python bindings

- Various functions in the Python bindings construct lists of objects, but
  assume that all calls succeed. Each of these could segfault under
  low-memory conditions: if the PyList_New() call fails,
  PyList_Append(NULL, item ) will segfault. Similarly, although
  Py_List_Append(list, NULL) is safe, Py_DECREF(NULL) will segfault.

Signed-off-by: Ales Kozumplik <akozumpl@redhat.com>
This commit is contained in:
David Malcolm 2011-12-15 22:24:19 -05:00 committed by Ales Kozumplik
parent 59807943af
commit 3157d6d7b7
4 changed files with 58 additions and 7 deletions

View File

@ -132,12 +132,23 @@ struct hdrObject_s {
static PyObject * hdrKeyList(hdrObject * s)
{
PyObject * keys = PyList_New(0);
HeaderIterator hi = headerInitIterator(s->h);
PyObject * keys;
HeaderIterator hi;
rpmTagVal tag;
keys = PyList_New(0);
if (!keys) {
return NULL;
}
hi = headerInitIterator(s->h);
while ((tag = headerNextTag(hi)) != RPMTAG_NOT_FOUND) {
PyObject *to = PyInt_FromLong(tag);
if (!to) {
headerFreeIterator(hi);
Py_DECREF(keys);
return NULL;
}
PyList_Append(keys, to);
Py_DECREF(to);
}

View File

@ -125,12 +125,24 @@ PyObject *rpmprob_Wrap(PyTypeObject *subtype, rpmProblem prob)
PyObject *rpmps_AsList(rpmps ps)
{
PyObject *problems = PyList_New(0);
rpmpsi psi = rpmpsInitIterator(ps);
PyObject *problems;
rpmpsi psi;
rpmProblem prob;
problems = PyList_New(0);
if (!problems) {
return NULL;
}
psi = rpmpsInitIterator(ps);
while ((prob = rpmpsiNext(psi))) {
PyObject *pyprob = rpmprob_Wrap(&rpmProblem_Type, prob);
if (!pyprob) {
Py_DECREF(problems);
rpmpsFreeIterator(psi);
return NULL;
}
PyList_Append(problems, pyprob);
Py_DECREF(pyprob);
}

View File

@ -44,8 +44,15 @@ PyObject *rpmtd_AsPyobj(rpmtd td)
if (array) {
res = PyList_New(0);
if (!res) {
return NULL;
}
while (rpmtdNext(td) >= 0) {
PyObject *item = rpmtd_ItemAsPyobj(td, tclass);
if (!item) {
Py_DECREF(res);
return NULL;
}
PyList_Append(res, item);
Py_DECREF(item);
}

View File

@ -151,15 +151,24 @@ static PyObject * spec_get_clean(specObject * s, void *closure)
static PyObject * spec_get_sources(specObject *s, void *closure)
{
PyObject *sourceList = PyList_New(0);
PyObject *sourceList;
rpmSpecSrc source;
sourceList = PyList_New(0);
if (!sourceList) {
return NULL;
}
rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
PyObject *srcUrl = Py_BuildValue("(sii)",
rpmSpecSrcFilename(source, 1),
rpmSpecSrcNum(source),
rpmSpecSrcFlags(source));
if (!srcUrl) {
Py_DECREF(sourceList);
return NULL;
}
PyList_Append(sourceList, srcUrl);
Py_DECREF(srcUrl);
}
@ -172,11 +181,23 @@ static PyObject * spec_get_sources(specObject *s, void *closure)
static PyObject * spec_get_packages(specObject *s, void *closure)
{
rpmSpecPkg pkg;
PyObject *pkgList = PyList_New(0);
rpmSpecPkgIter iter = rpmSpecPkgIterInit(s->spec);
PyObject *pkgList;
rpmSpecPkgIter iter;
pkgList = PyList_New(0);
if (!pkgList) {
return NULL;
}
iter = rpmSpecPkgIterInit(s->spec);
while ((pkg = rpmSpecPkgIterNext(iter)) != NULL) {
PyObject *po = specPkg_Wrap(&specPkg_Type, pkg);
if (!po) {
rpmSpecPkgIterFree(iter);
Py_DECREF(pkgList);
return NULL;
}
PyList_Append(pkgList, po);
Py_DECREF(po);
}