Remote: harden the resfpec setters
The object passed must be a list of strings, so make sure we fail by raising an error instead of segfaulting.
This commit is contained in:
42
src/remote.c
42
src/remote.c
@@ -373,13 +373,16 @@ get_pylist_from_git_strarray(git_strarray *strarray)
|
|||||||
int
|
int
|
||||||
get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist)
|
get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist)
|
||||||
{
|
{
|
||||||
long index, n;
|
Py_ssize_t index, n;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
n = PyObject_Length(pylist);
|
if (!PyList_Check(pylist)) {
|
||||||
if (n < 0)
|
PyErr_SetString(PyExc_TypeError, "Value must be a list");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = PyList_Size(pylist);
|
||||||
|
|
||||||
/* allocate new git_strarray */
|
/* allocate new git_strarray */
|
||||||
ptr = calloc(n, sizeof(char *));
|
ptr = calloc(n, sizeof(char *));
|
||||||
@@ -393,10 +396,23 @@ get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist)
|
|||||||
|
|
||||||
for (index = 0; index < n; index++) {
|
for (index = 0; index < n; index++) {
|
||||||
item = PyList_GetItem(pylist, index);
|
item = PyList_GetItem(pylist, index);
|
||||||
array->strings[index] = py_str_to_c_str(item, NULL);
|
char *str = py_str_to_c_str(item, NULL);
|
||||||
|
if (!str)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
array->strings[index] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GIT_OK;
|
return 0;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
n = index;
|
||||||
|
for (index = 0; index < n; index++) {
|
||||||
|
free(array->strings[index]);
|
||||||
|
}
|
||||||
|
free(array->strings);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Remote_fetch_refspecs__doc__, "Fetch refspecs");
|
PyDoc_STRVAR(Remote_fetch_refspecs__doc__, "Fetch refspecs");
|
||||||
@@ -419,16 +435,12 @@ Remote_fetch_refspecs__get__(Remote *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Remote_fetch_refspecs__set__(Remote *self, PyObject *args)
|
Remote_fetch_refspecs__set__(Remote *self, PyObject *py_list)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
PyObject *pyrefspecs;
|
|
||||||
git_strarray fetch_refspecs;
|
git_strarray fetch_refspecs;
|
||||||
|
|
||||||
if (! PyArg_Parse(args, "O", &pyrefspecs))
|
if (get_strarraygit_from_pylist(&fetch_refspecs, py_list) < 0)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (get_strarraygit_from_pylist(&fetch_refspecs, pyrefspecs) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
err = git_remote_set_fetch_refspecs(self->remote, &fetch_refspecs);
|
err = git_remote_set_fetch_refspecs(self->remote, &fetch_refspecs);
|
||||||
@@ -462,16 +474,12 @@ Remote_push_refspecs__get__(Remote *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Remote_push_refspecs__set__(Remote *self, PyObject *args)
|
Remote_push_refspecs__set__(Remote *self, PyObject *py_list)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
PyObject *pyrefspecs;
|
|
||||||
git_strarray push_refspecs;
|
git_strarray push_refspecs;
|
||||||
|
|
||||||
if (! PyArg_Parse(args, "O", &pyrefspecs))
|
if (get_strarraygit_from_pylist(&push_refspecs, py_list) != 0)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (get_strarraygit_from_pylist(&push_refspecs, pyrefspecs) != 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
err = git_remote_set_push_refspecs(self->remote, &push_refspecs);
|
err = git_remote_set_push_refspecs(self->remote, &push_refspecs);
|
||||||
|
@@ -130,6 +130,10 @@ class RepositoryTest(utils.RepoTestCase):
|
|||||||
'+refs/test/*:refs/test/remotes/*'
|
'+refs/test/*:refs/test/remotes/*'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, setattr, remote, 'push_refspecs', '+refs/*:refs/*')
|
||||||
|
self.assertRaises(TypeError, setattr, remote, 'fetch_refspecs', '+refs/*:refs/*')
|
||||||
|
self.assertRaises(TypeError, setattr, remote, 'fetch_refspecs', ['+refs/*:refs/*', 5])
|
||||||
|
|
||||||
self.assertEqual('+refs/*:refs/remotes/*',
|
self.assertEqual('+refs/*:refs/remotes/*',
|
||||||
remote.get_push_refspecs()[0])
|
remote.get_push_refspecs()[0])
|
||||||
self.assertEqual('+refs/test/*:refs/test/remotes/*',
|
self.assertEqual('+refs/test/*:refs/test/remotes/*',
|
||||||
|
Reference in New Issue
Block a user