Submitter | Boris Feld |
---|---|
Date | Nov. 22, 2018, 6:08 p.m. |
Message ID | <b6fff7b07488608fe8ea.1542910083@localhost.localdomain> |
Download | mbox | patch |
Permalink | /patch/36717/ |
State | Accepted |
Headers | show |
Comments
On Thu, 22 Nov 2018 19:08:03 +0100, Boris Feld wrote: > # HG changeset patch > # User Boris Feld <boris.feld@octobus.net> > # Date 1542725358 0 > # Tue Nov 20 14:49:18 2018 +0000 > # Node ID b6fff7b07488608fe8ea86ffb69a74037ed15cbe > # Parent 4369c00a8ee168565fba97112283bbc00be8ce44 > # EXP-Topic sparse-perf > # Available At https://bitbucket.org/octobus/mercurial-devel/ > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r b6fff7b07488 > sparse-revlog: add a `index_get_start` function in C Queued the series, many thanks. > +static inline int64_t index_get_start(indexObject *self, Py_ssize_t rev) > +{ > + uint64_t offset; > + if (rev >= self->length) { > + PyObject *tuple; > + PyObject *pylong; > + PY_LONG_LONG tmp; > + tuple = PyList_GET_ITEM(self->added, rev - self->length); > + pylong = PyTuple_GET_ITEM(tuple, 0); > + tmp = PyLong_AsLongLong(pylong); > + if (tmp == -1 && PyErr_Occurred()) { > + return -1; > + } > + if (tmp < 0) { > + PyErr_Format(PyExc_OverflowError, > + "revlog entry size out of bound (%llu)", > + (unsigned long long)tmp); Changed this to %lld (long long)tmp. If PyLong_AsLongLong() returned a negative integer, it would be really a negative Python long integer.
Patch
diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -185,6 +185,39 @@ static inline int index_get_parents(inde return 0; } +static inline int64_t index_get_start(indexObject *self, Py_ssize_t rev) +{ + uint64_t offset; + if (rev >= self->length) { + PyObject *tuple; + PyObject *pylong; + PY_LONG_LONG tmp; + tuple = PyList_GET_ITEM(self->added, rev - self->length); + pylong = PyTuple_GET_ITEM(tuple, 0); + tmp = PyLong_AsLongLong(pylong); + if (tmp == -1 && PyErr_Occurred()) { + return -1; + } + if (tmp < 0) { + PyErr_Format(PyExc_OverflowError, + "revlog entry size out of bound (%llu)", + (unsigned long long)tmp); + return -1; + } + offset = (uint64_t)tmp; + } else { + const char *data = index_deref(self, rev); + offset = getbe32(data + 4); + if (rev == 0) /* mask out version number for the first entry */ + offset &= 0xFFFF; + else { + uint32_t offset_high = getbe32(data); + offset |= ((uint64_t)offset_high) << 32; + } + } + return (int64_t)(offset >> 16); +} + /* * RevlogNG format (all in big endian, data may be inlined): * 6 bytes: offset