Mercurial > hg
comparison mercurial/cext/revlog.c @ 41018:f4113489e4d4 stable
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.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Thu, 27 Dec 2018 23:34:37 +0100 |
parents | 884321cd26c3 |
children | 7542466b94e2 46e0563c67db |
comparison
equal
deleted
inserted
replaced
41017:d7d3164e6a31 | 41018:f4113489e4d4 |
---|---|
840 * Callers must ensure that rev >= 0 or illegal memory access may occur. | 840 * Callers must ensure that rev >= 0 or illegal memory access may occur. |
841 */ | 841 */ |
842 static inline int index_baserev(indexObject *self, int rev) | 842 static inline int index_baserev(indexObject *self, int rev) |
843 { | 843 { |
844 const char *data; | 844 const char *data; |
845 int result; | |
845 | 846 |
846 if (rev >= self->length) { | 847 if (rev >= self->length) { |
847 PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); | 848 PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); |
848 return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); | 849 result = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); |
849 } | 850 } |
850 else { | 851 else { |
851 data = index_deref(self, rev); | 852 data = index_deref(self, rev); |
852 if (data == NULL) { | 853 if (data == NULL) { |
853 return -2; | 854 return -2; |
854 } | 855 } |
855 | 856 |
856 return getbe32(data + 16); | 857 result = getbe32(data + 16); |
857 } | 858 } |
859 if (result > rev) { | |
860 PyErr_Format( | |
861 PyExc_ValueError, | |
862 "corrupted revlog, revision base above revision: %d, %d", | |
863 rev, result); | |
864 return -2; | |
865 } | |
866 return result; | |
858 } | 867 } |
859 | 868 |
860 static PyObject *index_deltachain(indexObject *self, PyObject *args) | 869 static PyObject *index_deltachain(indexObject *self, PyObject *args) |
861 { | 870 { |
862 int rev, generaldelta; | 871 int rev, generaldelta; |