diff options
Diffstat (limited to '')
| -rw-r--r-- | lang/python/gpgme.i | 53 | ||||
| -rw-r--r-- | lang/python/helpers.c | 38 | 
2 files changed, 78 insertions, 13 deletions
| diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index dfa3775c..bc957e57 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -36,11 +36,16 @@  /* Allow use of Unicode objects, bytes, and None for strings.  */ -%typemap(in) const char * { +%typemap(in) const char *(PyObject *encodedInput = NULL) {    if ($input == Py_None)      $1 = NULL;    else if (PyUnicode_Check($input)) -    $1 = PyUnicode_AsUTF8($input); +    { +      encodedInput = PyUnicode_AsUTF8String($input); +      if (encodedInput == NULL) +        return NULL; +      $1 = PyBytes_AsString(encodedInput); +    }    else if (PyBytes_Check($input))      $1 = PyBytes_AsString($input);    else { @@ -50,19 +55,35 @@      return NULL;    }  } -%typemap(freearg) const char * ""; +%typemap(freearg) const char * { +  Py_XDECREF(encodedInput$argnum); +}  /* Likewise for a list of strings.  */ -%typemap(in) const char *[] (void *vector = NULL) { +%typemap(in) const char *[] (void *vector = NULL, +                             size_t size, +                             PyObject **pyVector = NULL) {    /* Check if is a list */    if (PyList_Check($input)) { -    size_t i, size = PyList_Size($input); +    size_t i, j; +    size = PyList_Size($input);      $1 = (char **) (vector = malloc((size+1) * sizeof(char *))); +    pyVector = calloc(sizeof *pyVector, size);      for (i = 0; i < size; i++) {        PyObject *o = PyList_GetItem($input,i);        if (PyUnicode_Check(o)) -        $1[i] = PyUnicode_AsUTF8(o); +        { +          pyVector[i] = PyUnicode_AsUTF8String(o); +          if (pyVector[i] == NULL) +            { +              free(vector); +              for (j = 0; j < i; j++) +                Py_XDECREF(pyVector[j]); +              return NULL; +            } +          $1[i] = PyBytes_AsString(pyVector[i]); +        }        else if (PyString_Check(o))  	$1[i] = PyString_AsString(o);        else { @@ -83,7 +104,10 @@    }  }  %typemap(freearg) const char *[] { +  size_t i;    free(vector$argnum); +  for (i = 0; i < size$argnum; i++) +    Py_XDECREF(pyVector$argnum[i]);  }  // Release returned buffers as necessary. @@ -296,13 +320,22 @@  }  /* For gpgme_data_write, but should be universal.  */ -%typemap(in) (const void *buffer, size_t size) { +%typemap(in) (const void *buffer, size_t size)(PyObject *encodedInput = NULL) {    Py_ssize_t ssize;    if ($input == Py_None)      $1 = NULL, $2 = 0;    else if (PyUnicode_Check($input)) -    $1 = PyUnicode_AsUTF8AndSize($input, &ssize); +    { +      encodedInput = PyUnicode_AsUTF8String($input); +      if (encodedInput == NULL) +        return NULL; +      if (PyBytes_AsStringAndSize(encodedInput, (char **) &$1, &ssize) == -1) +        { +          Py_DECREF(encodedInput); +          return NULL; +        } +    }    else if (PyBytes_Check($input))      PyBytes_AsStringAndSize($input, (char **) &$1, &ssize);    else { @@ -320,7 +353,9 @@        $2 = (size_t) ssize;      }  } -%typemap(freearg) (const void *buffer, size_t size) ""; +%typemap(freearg) (const void *buffer, size_t size) { +  Py_XDECREF(encodedInput$argnum); +}  // Make types containing 'next' field to be lists  %ignore next; diff --git a/lang/python/helpers.c b/lang/python/helpers.c index 0b4a7736..6e63c97a 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -191,14 +191,17 @@ _pyme_obj2gpgme_t(PyObject *input, const char *objtype, int argnum)    pyname = PyObject_GetAttrString(input, "_ctype");    if (pyname && PyUnicode_Check(pyname))      { -      if (strcmp(PyUnicode_AsUTF8(pyname), objtype) != 0) +      PyObject *encoded = PyUnicode_AsUTF8String(pyname); +      if (strcmp(PyBytes_AsString(encoded), objtype) != 0)          {            PyErr_Format(PyExc_TypeError,                         "arg %d: Expected value of type %s, but got %s", -                       argnum, objtype, PyUnicode_AsUTF8(pyname)); +                       argnum, objtype, PyBytes_AsString(encoded)); +          Py_DECREF(encoded);            Py_DECREF(pyname);            return NULL;          } +      Py_DECREF(encoded);      }    else      return NULL; @@ -334,6 +337,7 @@ static gpgme_error_t pyPassphraseCb(void *hook,    PyObject *args = NULL;    PyObject *retval = NULL;    PyObject *dataarg = NULL; +  PyObject *encoded = NULL;    gpgme_error_t err_status = 0;    _pyme_exception_init(); @@ -388,7 +392,17 @@ static gpgme_error_t pyPassphraseCb(void *hook,        else if (PyUnicode_Check(retval))          {            Py_ssize_t ssize; -          buf = PyUnicode_AsUTF8AndSize(retval, &ssize); +          encoded = PyUnicode_AsUTF8String(retval); +          if (encoded == NULL) +            { +              err_status = gpg_error(GPG_ERR_GENERAL); +              goto leave; +            } +          if (PyBytes_AsStringAndSize(encoded, &buf, &ssize) == -1) +            { +              err_status = gpg_error(GPG_ERR_GENERAL); +              goto leave; +            }            assert (! buf || ssize >= 0);            len = (size_t) ssize;          } @@ -418,6 +432,7 @@ static gpgme_error_t pyPassphraseCb(void *hook,    if (err_status)      _pyme_stash_callback_exception(self); +  Py_XDECREF(encoded);    return err_status;  } @@ -676,10 +691,23 @@ gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,      err_status = _pyme_exception2code();    } else {      if (fd>=0 && retval && PyUnicode_Check(retval)) { +      PyObject *encoded = NULL;        const char *buffer;        Py_ssize_t size; -      buffer = PyUnicode_AsUTF8AndSize(retval, &size); +      encoded = PyUnicode_AsUTF8String(retval); +      if (encoded == NULL) +        { +          err_status = gpg_error(GPG_ERR_GENERAL); +          goto leave; +        } +      if (PyBytes_AsStringAndSize(encoded, &buffer, &size) == -1) +        { +          Py_DECREF(encoded); +          err_status = gpg_error(GPG_ERR_GENERAL); +          goto leave; +        } +        if (write(fd, buffer, size) < 0) {          err_status = gpgme_error_from_syserror ();          _pyme_raise_exception (err_status); @@ -688,8 +716,10 @@ gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,          err_status = gpgme_error_from_syserror ();          _pyme_raise_exception (err_status);        } +      Py_DECREF(encoded);      }    } + leave:    if (err_status)      _pyme_stash_callback_exception(self); | 
