Mercurial > hg
changeset 26017:44705659da94
reachableroots: verify integer range of heads argument (issue4775)
Now it raises IndexError instead of SEGV for 'wdir()' as it was before.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 13 Aug 2015 18:38:46 +0900 |
parents | c8d41c9c23c7 |
children | c6115c30a376 |
files | mercurial/parsers.c tests/test-parseindex.t |
diffstat | 2 files changed, 37 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/parsers.c Thu Aug 13 18:29:38 2015 +0900 +++ b/mercurial/parsers.c Thu Aug 13 18:38:46 2015 +0900 @@ -1167,6 +1167,10 @@ numheads = PyList_GET_SIZE(heads); for (i = 0; i < numheads; i++) { revnum = PyInt_AS_LONG(PyList_GET_ITEM(heads, i)); + if (revnum + 1 < 0 || revnum + 1 >= len + 1) { + PyErr_SetString(PyExc_IndexError, "head out of range"); + goto bail; + } if (seen[revnum+1] == 0) { tovisit[lentovisit++] = revnum; seen[revnum+1]=1;
--- a/tests/test-parseindex.t Thu Aug 13 18:29:38 2015 +0900 +++ b/tests/test-parseindex.t Thu Aug 13 18:38:46 2015 +0900 @@ -60,9 +60,40 @@ $ cd .. -Test corrupted p1/p2 fields that could cause SEGV at parsers.c: +#if no-pure + +Test SEGV caused by bad revision passed to reachableroots() (issue4775): + + $ cd a -#if no-pure + $ python <<EOF + > from mercurial import changelog, scmutil + > cl = changelog.changelog(scmutil.vfs('.hg/store')) + > print 'goods:' + > 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]: + > print '%s:' % head, + > try: + > cl.reachableroots(0, [head], set([0])) + > print 'uncaught buffer overflow?' + > except IndexError as inst: + > print inst + > EOF + goods: + 0: <baseset [0]> + 1: <baseset [0]> + -1: <baseset []> + bads: + 2: head out of range + 10000: head out of range + -2: head out of range + -10000: head out of range + + $ cd .. + +Test corrupted p1/p2 fields that could cause SEGV at parsers.c: $ mkdir invalidparent $ cd invalidparent