python: Fix convert_tuple_to_char_pointer_array

This finally fixes a few issues with the magic convert_tuple_to_char_pointer_array function. This now clearly copies the char* from the python object so we don't end up keeping reference to those. Also add the few required free calls to free the content of the array. Signed-off-by: 's avatarStéphane Graber <stgraber@ubuntu.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 93d564ed
...@@ -35,7 +35,7 @@ typedef struct { ...@@ -35,7 +35,7 @@ typedef struct {
char** char**
convert_tuple_to_char_pointer_array(PyObject *argv) { convert_tuple_to_char_pointer_array(PyObject *argv) {
int argc = PyTuple_GET_SIZE(argv); int argc = PyTuple_GET_SIZE(argv);
int i; int i, j;
char **result = (char**) malloc(sizeof(char*)*argc + 1); char **result = (char**) malloc(sizeof(char*)*argc + 1);
...@@ -49,30 +49,46 @@ convert_tuple_to_char_pointer_array(PyObject *argv) { ...@@ -49,30 +49,46 @@ convert_tuple_to_char_pointer_array(PyObject *argv) {
assert(pyobj != NULL); assert(pyobj != NULL);
char *str = NULL; char *str = NULL;
PyObject *pystr = NULL;
if (!PyUnicode_Check(pyobj)) { if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string"); PyErr_SetString(PyExc_ValueError, "Expected a string");
free(result); goto error;
return NULL;
} }
pystr = PyUnicode_AsUTF8String(pyobj); str = PyUnicode_AsUTF8(pyobj);
if (pystr == NULL) { if (!str) {
PyErr_SetString(PyExc_ValueError, "Unable to convert to UTF-8"); /* Maybe it wasn't UTF-8 encoded. An exception is already set. */
free(result); goto error;
return NULL;
} }
str = PyBytes_AsString(pystr); /* We must make a copy of str, because it points into internal memory
assert(str != NULL); * which we do not own. Assume it's NULL terminated, otherwise we'd
* have to use PyUnicode_AsUTF8AndSize() and be explicit about copying
* the memory.
*/
result[i] = strdup(str);
memcpy((char *) &result[i], (char *) &str, sizeof(str)); /* Do not decref pyobj since we stole a reference by using
Py_DECREF(pystr); * PyTuple_GET_ITEM().
*/
if (result[i] == NULL) {
PyErr_SetNone(PyExc_MemoryError);
goto error;
}
} }
result[argc] = NULL; result[argc] = NULL;
return result; return result;
error:
/* We can only iterate up to but not including i because malloc() does not
* initialize its memory. Thus if we got here, i points to the index
* after the last strdup'd entry in result.
*/
for (j = 0; j < i; j++)
free(result[j]);
free(result);
return NULL;
} }
static void static void
...@@ -203,6 +219,7 @@ Container_create(Container *self, PyObject *args, PyObject *kwds) ...@@ -203,6 +219,7 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
char* template_name = NULL; char* template_name = NULL;
char** create_args = {NULL}; char** create_args = {NULL};
PyObject *retval = NULL, *vargs = NULL; PyObject *retval = NULL, *vargs = NULL;
int i = 0;
static char *kwlist[] = {"template", "args", NULL}; static char *kwlist[] = {"template", "args", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist, if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
...@@ -231,6 +248,8 @@ Container_create(Container *self, PyObject *args, PyObject *kwds) ...@@ -231,6 +248,8 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
/* We cannot have gotten here unless vargs was given and create_args /* We cannot have gotten here unless vargs was given and create_args
* was successfully allocated. * was successfully allocated.
*/ */
for (i = 0; i < PyTuple_GET_SIZE(vargs); i++)
free(create_args[i]);
free(create_args); free(create_args);
} }
...@@ -495,7 +514,7 @@ Container_start(Container *self, PyObject *args, PyObject *kwds) ...@@ -495,7 +514,7 @@ Container_start(Container *self, PyObject *args, PyObject *kwds)
{ {
char** init_args = {NULL}; char** init_args = {NULL};
PyObject *useinit = NULL, *retval = NULL, *vargs = NULL; PyObject *useinit = NULL, *retval = NULL, *vargs = NULL;
int init_useinit = 0; int init_useinit = 0, i = 0;
static char *kwlist[] = {"useinit", "cmd", NULL}; static char *kwlist[] = {"useinit", "cmd", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
...@@ -524,6 +543,8 @@ Container_start(Container *self, PyObject *args, PyObject *kwds) ...@@ -524,6 +543,8 @@ Container_start(Container *self, PyObject *args, PyObject *kwds)
/* We cannot have gotten here unless vargs was given and create_args /* We cannot have gotten here unless vargs was given and create_args
* was successfully allocated. * was successfully allocated.
*/ */
for (i = 0; i < PyTuple_GET_SIZE(vargs); i++)
free(init_args[i]);
free(init_args); free(init_args);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment