diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg index d55961497..8dd77c308 100644 --- a/Lib/python/pystrings.swg +++ b/Lib/python/pystrings.swg @@ -6,47 +6,47 @@ SWIGINTERN int SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) { - static swig_type_info* pchar_info = 0; - char* vptr = 0; - if (!pchar_info) pchar_info = SWIG_TypeQuery("char *"); - if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_info, 0) == SWIG_OK) { - if (cptr) *cptr = vptr; - if (psize) *psize = vptr ? (strlen(vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; + if (PyString_Check(obj)) { + char *cstr; int len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = %new_copy_array(cstr, len + 1, char); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = PyString_AsString(obj); + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; return SWIG_OK; } else { - if (PyString_Check(obj)) { - char *cstr; int len; - PyString_AsStringAndSize(obj, &cstr, &len); - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation, so, by default we return a copy of - the buffer, as in the wstring case. - - But, if you use the -DSWIG_PYTHON_UNSAFE_CSTR at - compilation time, you will get, at your own risk, the - inner string pointer instead, when possible. - */ -#ifndef SWIG_PYTHON_UNSAFE_CSTR - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = %new_copy_array(cstr, len + 1, char); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = PyString_AsString(obj); - *alloc = SWIG_OLDOBJ; - } - } else { - *cptr = PyString_AsString(obj); - } - } - if (psize) *psize = len + 1; + char* vptr = 0; + static swig_type_info* pchar_info = 0; + if (!pchar_info) pchar_info = SWIG_TypeQuery("char *"); + if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_info, 0) == SWIG_OK) { + if (cptr) *cptr = vptr; + if (psize) *psize = vptr ? (strlen(vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; return SWIG_OK; } } diff --git a/Lib/python/pywstrings.swg b/Lib/python/pywstrings.swg index a9c8b4024..915875e95 100644 --- a/Lib/python/pywstrings.swg +++ b/Lib/python/pywstrings.swg @@ -6,32 +6,32 @@ SWIGINTERN int SWIG_AsWCharPtrAndSize(PyObject *obj, wchar_t **cptr, size_t *psize, int *alloc) { - static swig_type_info* pwchar_info = 0; - wchar_t * vptr = 0; - if (!pwchar_info) pwchar_info = SWIG_TypeQuery("wchar_t *"); - if (SWIG_ConvertPtr(obj, (void**)&vptr, pwchar_info, 0) == SWIG_OK) { - if (cptr) *cptr = vptr; - if (psize) *psize = vptr ? (wcslen(vptr) + 1) : 0; + PyObject *tmp = 0; + int isunicode = PyUnicode_Check(obj); + if (!isunicode && PyString_Check(obj)) { + if (cptr) { + obj = tmp = PyUnicode_FromObject(obj); + } + isunicode = 1; + } + if (isunicode) { + int len = PyUnicode_GetSize(obj); + if (cptr) { + *cptr = %new_array(len + 1, wchar_t); + PyUnicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len); + (*cptr)[len] = 0; + } + if (psize) *psize = (size_t) len + 1; + if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; + if (tmp) Py_DECREF(tmp); return SWIG_OK; } else { - PyObject *tmp = 0; - int isunicode = PyUnicode_Check(obj); - if (!isunicode && PyString_Check(obj)) { - if (cptr) { - obj = tmp = PyUnicode_FromObject(obj); - } - isunicode = 1; - } - if (isunicode) { - int len = PyUnicode_GetSize(obj); - if (cptr) { - *cptr = %new_array(len + 1, wchar_t); - PyUnicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len); - (*cptr)[len] = 0; - } - if (psize) *psize = (size_t) len + 1; - if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; - if (tmp) Py_DECREF(tmp); + static swig_type_info* pwchar_info = 0; + wchar_t * vptr = 0; + if (!pwchar_info) pwchar_info = SWIG_TypeQuery("wchar_t *"); + if (SWIG_ConvertPtr(obj, (void**)&vptr, pwchar_info, 0) == SWIG_OK) { + if (cptr) *cptr = vptr; + if (psize) *psize = vptr ? (wcslen(vptr) + 1) : 0; return SWIG_OK; } } diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 8c70a3ae1..634f029c9 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -62,6 +62,7 @@ static int threads = 0; static int nothreads = 0; static int classptr = 0; static int shadowimport = 1; +static int safecstrings = 0; /* flags for the make_autodoc function */ enum autodoc_t { @@ -95,6 +96,8 @@ Python Options (available with -python)\n\ -noh - Don't generate the output header file\n\ -noproxy - Don't generate proxy classes \n\ -noproxyimport - Don't insert proxy import statements derived from the %import directive \n\ + -safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\ + -nosafecstrings - Avoid extra strings copies when possible (default)\n\ \n"; class PYTHON : public Language { @@ -254,6 +257,12 @@ public: /* Turn off thread suppor mode */ nothreads = 1; Swig_mark_arg(i); + } else if (strcmp(argv[i],"-safecstrings") == 0) { + safecstrings = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-nosafecstrings") == 0) { + safecstrings = 0; + Swig_mark_arg(i); } else if (strcmp(argv[i],"-modern") == 0) { apply = 0; classic = 0; @@ -383,6 +392,11 @@ public: Printf(f_runtime,"#define SWIG_PYTHON_THREADS\n"); } + if (safecstrings) { + Printf(f_runtime,"#define SWIG_PYTHON_SAFE_CSTRINGS\n"); + } + + /* Set module name */ module = Copy(Getattr(n,"name")); mainmodule = Getattr(n,"name");