[lxc-devel] [PATCH] python: Fix convert_tuple_to_char_pointer_array
Stéphane Graber
stgraber at ubuntu.com
Tue Apr 23 22:52:41 UTC 2013
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: Stéphane Graber <stgraber at ubuntu.com>
---
src/python-lxc/lxc.c | 51 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c
index 85bab11..85710d6 100644
--- a/src/python-lxc/lxc.c
+++ b/src/python-lxc/lxc.c
@@ -35,7 +35,7 @@ typedef struct {
char**
convert_tuple_to_char_pointer_array(PyObject *argv) {
int argc = PyTuple_GET_SIZE(argv);
- int i;
+ int i, j;
char **result = (char**) malloc(sizeof(char*)*argc + 1);
@@ -49,30 +49,46 @@ convert_tuple_to_char_pointer_array(PyObject *argv) {
assert(pyobj != NULL);
char *str = NULL;
- PyObject *pystr = NULL;
+
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
- free(result);
- return NULL;
+ goto error;
}
- pystr = PyUnicode_AsUTF8String(pyobj);
- if (pystr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Unable to convert to UTF-8");
- free(result);
- return NULL;
+ str = PyUnicode_AsUTF8(pyobj);
+ if (!str) {
+ /* Maybe it wasn't UTF-8 encoded. An exception is already set. */
+ goto error;
}
- str = PyBytes_AsString(pystr);
- assert(str != NULL);
+ /* We must make a copy of str, because it points into internal memory
+ * 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));
- Py_DECREF(pystr);
+ /* Do not decref pyobj since we stole a reference by using
+ * PyTuple_GET_ITEM().
+ */
+ if (result[i] == NULL) {
+ PyErr_SetNone(PyExc_MemoryError);
+ goto error;
+ }
}
result[argc] = NULL;
-
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
@@ -203,6 +219,7 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
char* template_name = NULL;
char** create_args = {NULL};
PyObject *retval = NULL, *vargs = NULL;
+ int i = 0;
static char *kwlist[] = {"template", "args", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
@@ -231,6 +248,8 @@ Container_create(Container *self, PyObject *args, PyObject *kwds)
/* We cannot have gotten here unless vargs was given and create_args
* was successfully allocated.
*/
+ for (i = 0; i < PyTuple_GET_SIZE(vargs); i++)
+ free(create_args[i]);
free(create_args);
}
@@ -495,7 +514,7 @@ Container_start(Container *self, PyObject *args, PyObject *kwds)
{
char** init_args = {NULL};
PyObject *useinit = NULL, *retval = NULL, *vargs = NULL;
- int init_useinit = 0;
+ int init_useinit = 0, i = 0;
static char *kwlist[] = {"useinit", "cmd", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
@@ -524,6 +543,8 @@ Container_start(Container *self, PyObject *args, PyObject *kwds)
/* We cannot have gotten here unless vargs was given and create_args
* was successfully allocated.
*/
+ for (i = 0; i < PyTuple_GET_SIZE(vargs); i++)
+ free(init_args[i]);
free(init_args);
}
--
1.8.1.2
More information about the lxc-devel
mailing list