Fix the memory leak related to Python 3 unicode and char * conversion.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11160 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
359c4f786d
commit
a863d31e81
6 changed files with 67 additions and 10 deletions
|
|
@ -1,6 +1,21 @@
|
|||
Version 1.3.39 (in progress)
|
||||
============================
|
||||
|
||||
2009-03-19: bhy
|
||||
[Python] Fix the memory leak related to Python 3 unicode and C char* conversion,
|
||||
which can be shown in the following example before this fix:
|
||||
|
||||
from li_cstring import *
|
||||
i=0
|
||||
while True:
|
||||
i += 1
|
||||
n = str(i)*10
|
||||
test3(n)
|
||||
|
||||
This fix affected SWIG_AsCharPtrAndSize() so you cannot call this function with
|
||||
a null alloc and non-null cptr argument in Python 3, otherwise a runtime error
|
||||
will be raised.
|
||||
|
||||
2009-03-18: wsfulton
|
||||
[C#] std::vector<T> wrapper improvements for .NET 2 and also providing the
|
||||
necessary machinery to use the std::vector<T> wrappers with more advanced features such
|
||||
|
|
|
|||
|
|
@ -55,11 +55,13 @@ SWIG_Python_AddErrorMsg(const char* mesg)
|
|||
|
||||
if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
|
||||
if (value) {
|
||||
char *tmp;
|
||||
PyObject *old_str = PyObject_Str(value);
|
||||
PyErr_Clear();
|
||||
Py_XINCREF(type);
|
||||
|
||||
PyErr_Format(type, "%s %s", SWIG_Python_str_AsChar(old_str), mesg);
|
||||
PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
|
||||
SWIG_Python_str_DelForPy3(tmp);
|
||||
Py_DECREF(old_str);
|
||||
Py_DECREF(value);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -21,17 +21,35 @@
|
|||
# define SWIG_Python_str_FromFormat PyString_FromFormat
|
||||
#endif
|
||||
|
||||
|
||||
/* Warning: This function will allocate a new string in Python 3,
|
||||
* so please call SWIG_Python_str_DelForPy3(x) to free the space.
|
||||
*/
|
||||
SWIGINTERN char*
|
||||
SWIG_Python_str_AsChar(PyObject *str)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
char *cstr;
|
||||
char *newstr;
|
||||
int len;
|
||||
str = PyUnicode_AsUTF8String(str);
|
||||
return PyBytes_AsString(str);
|
||||
PyBytes_AsStringAndSize(str, &cstr, &len);
|
||||
newstr = (char *) malloc(len+1);
|
||||
memcpy(newstr, cstr, len+1);
|
||||
Py_XDECREF(str);
|
||||
return newstr;
|
||||
#else
|
||||
return PyString_AsString(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
|
||||
#else
|
||||
# define SWIG_Python_str_DelForPy3(x)
|
||||
#endif
|
||||
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
SWIG_Python_str_FromChar(const char *c)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,9 +80,11 @@ swig_varlink_str(swig_varlinkobject *v) {
|
|||
|
||||
SWIGINTERN int
|
||||
swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
|
||||
char *tmp;
|
||||
PyObject *str = swig_varlink_str(v);
|
||||
fprintf(fp,"Swig global variables ");
|
||||
fprintf(fp,"%s\n", SWIG_Python_str_AsChar(str));
|
||||
fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
|
||||
SWIG_Python_str_DelForPy3(tmp);
|
||||
Py_DECREF(str);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,13 +407,16 @@ SwigPyObject_repr(SwigPyObject *v, PyObject *args)
|
|||
SWIGRUNTIME int
|
||||
SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
|
||||
{
|
||||
char *str;
|
||||
#ifdef METH_NOARGS
|
||||
PyObject *repr = SwigPyObject_repr(v);
|
||||
#else
|
||||
PyObject *repr = SwigPyObject_repr(v, NULL);
|
||||
#endif
|
||||
if (repr) {
|
||||
fputs(SWIG_Python_str_AsChar(repr), fp);
|
||||
str = SWIG_Python_str_AsChar(repr);
|
||||
fputs(str, fp);
|
||||
SWIG_Python_str_DelForPy3(str);
|
||||
Py_DECREF(repr);
|
||||
return 0;
|
||||
} else {
|
||||
|
|
@ -1474,21 +1477,23 @@ SWIG_Python_TypeQuery(const char *type)
|
|||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_AddErrMesg(const char* mesg, int infront)
|
||||
{
|
||||
{
|
||||
if (PyErr_Occurred()) {
|
||||
PyObject *type = 0;
|
||||
PyObject *value = 0;
|
||||
PyObject *traceback = 0;
|
||||
PyErr_Fetch(&type, &value, &traceback);
|
||||
if (value) {
|
||||
char *tmp;
|
||||
PyObject *old_str = PyObject_Str(value);
|
||||
Py_XINCREF(type);
|
||||
PyErr_Clear();
|
||||
if (infront) {
|
||||
PyErr_Format(type, "%s %s", mesg, SWIG_Python_str_AsChar(old_str));
|
||||
PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
|
||||
} else {
|
||||
PyErr_Format(type, "%s %s", SWIG_Python_str_AsChar(old_str), mesg);
|
||||
PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
|
||||
}
|
||||
SWIG_Python_str_DelForPy3(tmp);
|
||||
Py_DECREF(old_str);
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -1540,6 +1545,7 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
|
|||
if (cstr) {
|
||||
PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
|
||||
type, otype, cstr);
|
||||
SWIG_Python_str_DelForPy3(cstr);
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
|
||||
type, otype);
|
||||
|
|
|
|||
|
|
@ -6,19 +6,27 @@ SWIGINTERN int
|
|||
SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
||||
{
|
||||
%#if PY_VERSION_HEX>=0x03000000
|
||||
if (PyUnicode_Check(obj))
|
||||
if (PyUnicode_Check(obj))
|
||||
%#else
|
||||
if (PyString_Check(obj))
|
||||
if (PyString_Check(obj))
|
||||
%#endif
|
||||
{
|
||||
char *cstr; Py_ssize_t len;
|
||||
%#if PY_VERSION_HEX>=0x03000000
|
||||
if (!alloc && cptr) {
|
||||
/* We can't allow converting without allocation, since the internal
|
||||
representation of string in Python 3 is UCS-2/UCS-4 but we require
|
||||
a UTF-8 representation.
|
||||
TODO(bhy) More detailed explanation */
|
||||
return SWIG_RuntimeError;
|
||||
}
|
||||
obj = PyUnicode_AsUTF8String(obj);
|
||||
PyBytes_AsStringAndSize(obj, &cstr, &len);
|
||||
if(alloc) *alloc = SWIG_NEWOBJ;
|
||||
%#else
|
||||
PyString_AsStringAndSize(obj, &cstr, &len);
|
||||
%#endif
|
||||
if (cptr) {
|
||||
if (cptr) {
|
||||
if (alloc) {
|
||||
/*
|
||||
In python the user should not be able to modify the inner
|
||||
|
|
@ -43,10 +51,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
|||
*alloc = SWIG_OLDOBJ;
|
||||
}
|
||||
} else {
|
||||
%#if PY_VERSION_HEX>=0x03000000
|
||||
assert(0); /* Should never reach here in Python 3 */
|
||||
%#endif
|
||||
*cptr = SWIG_Python_str_AsChar(obj);
|
||||
}
|
||||
}
|
||||
if (psize) *psize = len + 1;
|
||||
%#if PY_VERSION_HEX>=0x03000000
|
||||
Py_XDECREF(obj);
|
||||
%#endif
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue