From patchwork Thu Aug 13 10:48:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4,of,4] reachableroots: verify type of each item of heads argument From: Yuya Nishihara X-Patchwork-Id: 10203 Message-Id: <3e005964350afc0a39ce.1439462891@mimosa> To: mercurial-devel@selenic.com Date: Thu, 13 Aug 2015 19:48:11 +0900 # HG changeset patch # User Yuya Nishihara # Date 1439459989 -32400 # Thu Aug 13 18:59:49 2015 +0900 # Node ID 3e005964350afc0a39ce7fbade9409cb3ba1653f # Parent e650aa6ea4fb2866b5457ea3ba361db81d6ccba8 reachableroots: verify type of each item of heads argument Though PyInt_AS_LONG() can return a value no matter if it isn't an int object, it could exceed the boundary of the underlying struct. I think C API should be defensive to such errors. diff --git a/mercurial/parsers.c b/mercurial/parsers.c --- a/mercurial/parsers.c +++ b/mercurial/parsers.c @@ -1166,7 +1166,9 @@ static PyObject *reachableroots(indexObj /* Populate tovisit with all the heads */ numheads = PyList_GET_SIZE(heads); for (i = 0; i < numheads; i++) { - revnum = PyInt_AS_LONG(PyList_GET_ITEM(heads, i)); + revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i)); + if (revnum == -1 && PyErr_Occurred()) + goto bail; if (revnum + 1 < 0 || revnum + 1 >= len + 1) { PyErr_SetString(PyExc_IndexError, "head out of range"); goto bail; diff --git a/tests/test-parseindex.t b/tests/test-parseindex.t --- a/tests/test-parseindex.t +++ b/tests/test-parseindex.t @@ -73,12 +73,12 @@ Test SEGV caused by bad revision passed > for head in [0, len(cl) - 1, -1]: > print'%s: %r' % (head, cl.reachableroots(0, [head], set([0]))) > print 'bads:' - > for head in [len(cl), 10000, -2, -10000]: + > for head in [len(cl), 10000, -2, -10000, None]: > print '%s:' % head, > try: > cl.reachableroots(0, [head], set([0])) > print 'uncaught buffer overflow?' - > except IndexError as inst: + > except (IndexError, TypeError) as inst: > print inst > EOF goods: @@ -90,6 +90,7 @@ Test SEGV caused by bad revision passed 10000: head out of range -2: head out of range -10000: head out of range + None: an integer is required $ cd ..