Add missing checks for failures in calls to PyUnicode_AsUTF8String.

Previously a seg fault could occur when passing invalid UTF8 strings (low
surrogates), eg passing u"\udcff" to the C layer (Python 3).
This commit is contained in:
William S Fulton 2017-12-04 18:41:55 +00:00
commit b0e29fbdf3
12 changed files with 92 additions and 25 deletions

View file

@ -39,7 +39,11 @@ extern int gcd(int x, int y);
%#if PY_VERSION_HEX >= 0x03000000
{
PyObject *utf8str = PyUnicode_AsUTF8String(s);
const char *cstr = PyBytes_AsString(utf8str);
const char *cstr;
if (!utf8str) {
SWIG_fail;
}
cstr = PyBytes_AsString(utf8str);
$2[i] = strdup(cstr);
Py_DECREF(utf8str);
}
@ -72,6 +76,9 @@ extern int gcdmain(int argc, char *argv[]);
SWIG_fail;
}
utf8str = PyUnicode_AsUTF8String($input);
if (!utf8str) {
SWIG_fail;
}
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;
@ -105,6 +112,9 @@ extern int count(char *bytes, int len, char c);
char *cstr;
Py_ssize_t len;
PyObject *utf8str = PyUnicode_AsUTF8String($input);
if (!utf8str) {
SWIG_fail;
}
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;

View file

@ -25,3 +25,13 @@ if sys.version_info[0:2] < (3, 0):
check(unicode_strings.charstring(unicode("hello4")), "hello4")
unicode_strings.charstring(u"hell\xb05")
unicode_strings.charstring(u"hell\u00f66")
low_surrogate_string = u"\udcff"
try:
unicode_strings.instring(low_surrogate_string)
# Will succeed with Python 2
except TypeError, e:
# Python 3 will fail the PyUnicode_AsUTF8String conversion resulting in a TypeError.
# The real error is actually:
# UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed
pass

View file

@ -23,8 +23,11 @@
SWIG_fail;
}
pystr = PyUnicode_AsUTF8String(pyobj);
if (!pystr) {
SWIG_fail;
}
str = strdup(PyBytes_AsString(pystr));
Py_XDECREF(pystr);
Py_DECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");

View file

@ -20,4 +20,6 @@ char *charstring(char *s) {
return s;
}
void instring(const char *s) {
}
%}