# HG changeset patch # User Yuya Nishihara # Date 2015-08-14 03:31:56 # Node ID a3d5da8b641ee0a6336d708d839d3dad809fc86f # Parent 0b57b77f9b3ed5c1cc24ce95173c4f7e824df13f reachableroots: bail if integer object cannot be allocated This patch also replaces Py_XDECREF() by Py_DECREF() because we known "val" and "p" are not NULL. BTW, we can eliminate some of these allocation and error handling of int objects if the internal "seen" array has more information. For example, enum { SEEN = 1, ROOT = 2, REACHABLE = 4 }; /* ... build ROOT mask from roots argument ... */ if (seen[revnum + 1] & ROOT) { /* instead of PySet_Contains(roots, val) */ >From my quick hack, it is 2x faster. diff --git a/mercurial/parsers.c b/mercurial/parsers.c --- a/mercurial/parsers.c +++ b/mercurial/parsers.c @@ -1185,14 +1185,16 @@ static PyObject *reachableroots(indexObj /* Add the node to reachable if it is a root*/ revnum = tovisit[k++]; val = PyInt_FromLong(revnum); + if (val == NULL) + goto bail; if (PySet_Contains(roots, val) == 1) { PySet_Add(reachable, val); if (includepath == 0) { - Py_XDECREF(val); + Py_DECREF(val); continue; } } - Py_XDECREF(val); + Py_DECREF(val); /* Add its parents to the list of nodes to visit */ if (revnum != -1) { @@ -1223,9 +1225,15 @@ static PyObject *reachableroots(indexObj goto bail; for (k = 0; k < 2; k++) { PyObject *p = PyInt_FromLong(parents[k]); - if (PySet_Contains(reachable, p) == 1) - PySet_Add(reachable, PyInt_FromLong(i)); - Py_XDECREF(p); + if (p == NULL) + goto bail; + if (PySet_Contains(reachable, p) == 1) { + val = PyInt_FromLong(i); + if (val == NULL) + goto bail; + PySet_Add(reachable, val); + } + Py_DECREF(p); } } }