# HG changeset patch # User Boris Feld # Date 1545950077 -3600 # Node ID f4113489e4d493ffb0aa6c3c58454dc7e3b82e83 # Parent d7d3164e6a31193e8fa2fb9042183ce2487edb49 revlog: catch revlog corruption in index_baserev A revision cannot use a base above itself, it can only happens one corrupted repository. Ignoring such corrupted could lead to infinite loop. diff -r d7d3164e6a31 -r f4113489e4d4 mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c Fri Dec 21 17:36:12 2018 -0500 +++ b/mercurial/cext/revlog.c Thu Dec 27 23:34:37 2018 +0100 @@ -842,10 +842,11 @@ static inline int index_baserev(indexObject *self, int rev) { const char *data; + int result; if (rev >= self->length) { PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); - return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); + result = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); } else { data = index_deref(self, rev); @@ -853,8 +854,16 @@ return -2; } - return getbe32(data + 16); + result = getbe32(data + 16); } + if (result > rev) { + PyErr_Format( + PyExc_ValueError, + "corrupted revlog, revision base above revision: %d, %d", + rev, result); + return -2; + } + return result; } static PyObject *index_deltachain(indexObject *self, PyObject *args)