[lxc-devel] [PATCH] python: Fix convert_tuple_to_char_pointer_array

S.Çağlar Onur caglar at 10ur.org
Wed Apr 24 15:10:51 UTC 2013


Hi,

I'm getting this on ubuntu 12.10 with this

[...]

make[3]: Entering directory
`/home/caglar/Projects/lxc-upstream/src/python-lxc'
CFLAGS="-g -O2 -Wall -Werror -I ../../src -L../../src/lxc/"
/usr/bin/python3 setup.py build
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.2
creating build/lib.linux-x86_64-3.2/lxc
copying lxc/__init__.py -> build/lib.linux-x86_64-3.2/lxc
running build_ext
building '_lxc' extension
creating build/temp.linux-x86_64-3.2
gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -O2 -Wall
-Werror -I ../../src -L../../src/lxc/ -fPIC -I/usr/include/python3.2mu -c
lxc.c -o build/temp.linux-x86_64-3.2/lxc.o
lxc.c: In function ‘convert_tuple_to_char_pointer_array’:
lxc.c:58:9: error: implicit declaration of function ‘PyUnicode_AsUTF8’
[-Werror=implicit-function-declaration]
lxc.c:58:13: error: assignment makes pointer from integer without a cast
[-Werror]
cc1: all warnings being treated as errors
error: command 'gcc' failed with exit status 1
make[3]: *** [all] Error 1
make[3]: Leaving directory
`/home/caglar/Projects/lxc-upstream/src/python-lxc'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/caglar/Projects/lxc-upstream/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/caglar/Projects/lxc-upstream/src'
make: *** [all-recursive] Error 1

and quick grep shows no trace of PyUnicode_AsUTF8 but
PyUnicode_AsUTF8String function

[caglar at qgq:~/Projects/lxc-upstream(devel)] grep -r PyUnicode_AsUTF8
/usr/include/python3.2
/usr/include/python3.2/unicodeobject.h:# define PyUnicode_AsUTF8String
PyUnicodeUCS2_AsUTF8String
/usr/include/python3.2/unicodeobject.h:# define PyUnicode_AsUTF8String
PyUnicodeUCS4_AsUTF8String
/usr/include/python3.2/unicodeobject.h:   Same as PyUnicode_AsUTF8String()
except
/usr/include/python3.2/unicodeobject.h:   *** please use
PyUnicode_AsUTF8String() instead.
/usr/include/python3.2/unicodeobject.h:   *** please use
PyUnicode_AsUTF8String() instead.
/usr/include/python3.2/unicodeobject.h:PyAPI_FUNC(PyObject*)
PyUnicode_AsUTF8String(


On Tue, Apr 23, 2013 at 6:52 PM, Stéphane Graber <stgraber at ubuntu.com>wrote:

> 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
>
>
>
> ------------------------------------------------------------------------------
> Try New Relic Now & We'll Send You this Cool Shirt
> New Relic is the only SaaS-based application performance monitoring service
> that delivers powerful full stack analytics. Optimize and monitor your
> browser, app, & servers with just a few lines of code. Try New Relic
> and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel
>



-- 
S.Çağlar Onur <caglar at 10ur.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130424/5d58b7cb/attachment.html>


More information about the lxc-devel mailing list