Skip to content

Commit 0d9b7b3

Browse files
committed
Add surrogateescape for py3 builtin converters
1 parent 3e405b6 commit 0d9b7b3

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

src/converter/builtin_converters.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,19 @@ namespace
4848
#else
4949
void* convert_to_cstring(PyObject* obj)
5050
{
51-
return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
51+
if PyUnicode_Check(obj)
52+
{
53+
PyObject* pStrObj = PyUnicode_AsEncodedString(obj, "utf8", "surrogateescape");
54+
55+
if (PyErr_Occurred())
56+
throw_error_already_set();
57+
58+
char* zStr = PyBytes_AsString(pStrObj);
59+
char* zStrDup = strdup(zStr);
60+
Py_DECREF(pStrObj);
61+
return zStrDup;
62+
}
63+
return 0;
5264
}
5365
#endif
5466

@@ -367,7 +379,11 @@ namespace
367379
};
368380

369381
#if PY_VERSION_HEX >= 0x03000000
370-
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
382+
PyObject* UnicodeEncodeWithSurrogate (PyObject *unicode)
383+
{
384+
return PyUnicode_AsEncodedString(unicode, "utf8", "surrogateescape");
385+
}
386+
unaryfunc py_unicode_as_string_unaryfunc = UnicodeEncodeWithSurrogate;
371387
#endif
372388

373389
// A SlotPolicy for extracting C++ strings from Python objects.
@@ -486,7 +502,7 @@ namespace
486502
BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
487503
{
488504
#if PY_VERSION_HEX >= 0x03000000
489-
return PyUnicode_FromStringAndSize(&x, 1);
505+
return PyUnicode_DecodeUTF8(&x, 1, "surrogateescape");
490506
#else
491507
return PyString_FromStringAndSize(&x, 1);
492508
#endif
@@ -495,7 +511,7 @@ BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
495511
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
496512
{
497513
#if PY_VERSION_HEX >= 0x03000000
498-
return x ? PyUnicode_FromString(x) : boost::python::detail::none();
514+
return x ? PyUnicode_DecodeUTF8(x, strlen(x), "surrogateescape") : boost::python::detail::none();
499515
#else
500516
return x ? PyString_FromString(x) : boost::python::detail::none();
501517
#endif

0 commit comments

Comments
 (0)