dirstate: use tuple interface to fix leak in pack_dirstate()
Spotted by ASAN.
Unlike PyTuple_GET_ITEM(), PySequence_ITEM() returns a new reference. This
bug could be fixed by inserting Py_CLEAR() and Py_XDECREF() appropriately,
but I think requiring a tuple object is simpler and less error-prone.
The cext version is jumped to 10 since 6..9 are used in the default branch.
We'll need to bump it again at merge.
--- a/mercurial/cext/parsers.c Wed Sep 05 22:10:41 2018 +0900
+++ b/mercurial/cext/parsers.c Wed Sep 05 20:52:22 2018 +0900
@@ -382,12 +382,12 @@
char *p, *s;
int now;
- if (!PyArg_ParseTuple(args, "O!O!Oi:pack_dirstate", &PyDict_Type, &map,
- &PyDict_Type, ©map, &pl, &now))
+ if (!PyArg_ParseTuple(args, "O!O!O!i:pack_dirstate", &PyDict_Type, &map,
+ &PyDict_Type, ©map, &PyTuple_Type, &pl, &now))
return NULL;
- if (!PySequence_Check(pl) || PySequence_Size(pl) != 2) {
- PyErr_SetString(PyExc_TypeError, "expected 2-element sequence");
+ if (PyTuple_Size(pl) != 2) {
+ PyErr_SetString(PyExc_TypeError, "expected 2-element tuple");
return NULL;
}
@@ -416,14 +416,14 @@
p = PyBytes_AS_STRING(packobj);
- pn = PySequence_ITEM(pl, 0);
+ pn = PyTuple_GET_ITEM(pl, 0);
if (PyBytes_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
goto bail;
}
memcpy(p, s, l);
p += 20;
- pn = PySequence_ITEM(pl, 1);
+ pn = PyTuple_GET_ITEM(pl, 1);
if (PyBytes_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
goto bail;
@@ -713,7 +713,7 @@
void manifest_module_init(PyObject *mod);
void revlog_module_init(PyObject *mod);
-static const int version = 5;
+static const int version = 10;
static void module_init(PyObject *mod)
{
--- a/mercurial/dirstate.py Wed Sep 05 22:10:41 2018 +0900
+++ b/mercurial/dirstate.py Wed Sep 05 20:52:22 2018 +0900
@@ -1392,9 +1392,9 @@
l = len(st)
if l == 40:
- self._parents = st[:20], st[20:40]
+ self._parents = (st[:20], st[20:40])
elif l == 0:
- self._parents = [nullid, nullid]
+ self._parents = (nullid, nullid)
else:
raise error.Abort(_('working directory state appears '
'damaged!'))
--- a/mercurial/policy.py Wed Sep 05 22:10:41 2018 +0900
+++ b/mercurial/policy.py Wed Sep 05 20:52:22 2018 +0900
@@ -69,7 +69,7 @@
(r'cext', r'bdiff'): 3,
(r'cext', r'mpatch'): 1,
(r'cext', r'osutil'): 4,
- (r'cext', r'parsers'): 5,
+ (r'cext', r'parsers'): 10,
}
# map import request to other package or module