Hello,
We have 64bit linux cpp application with embeded python and pyside. Recently we
encountered problem with more than 2-bytes long unicode symbols:
>from PySide import QtCore
>QtCore.QUrl(u"\U0001F431").toString() # using u"\uD83D\uDC31" instead of
>u"\U0001F431" leads to the same result
>u'\U0001f431\u7f74' # 2 symbols string instead of one
last symbol is different each application run (it's some randomly filled
memory).
our exact environment is python 2.7.7 with Py_UNICODE_SIZE = 2, pyside 1.1.2
and qt 4.8.3 where sizeof(wchar_t) = 4.
Look in the QString converter-function at
PySide/QtCore/typesystem_core_common.xml:195
The source of problem is QString::toWCharArray function, which traslates 2
characters QString into single character wchar_t array and python
PyUnicode_FromWideChar doesn't set proper unicode string length to resulting
object when argument array have internal zeros. I attached patch which seems to
fix this problem.
If patch is not appropriate could someone tell me how to fix this properly?
*** /tmp/opt/linux-CentOS_4.4-x64/P7/pyside-1.1.2/share/PySide/typesystems/typesystem_core_common.xml 2014-06-25 12:59:39.000000000 +0400
--- ./sources/pyside/PySide/QtCore/typesystem_core_common.xml 2014-11-10 18:02:46.635206497 +0300
***************
*** 194,201 ****
<native-to-target>
const int N = %in.length();
wchar_t* str = new wchar_t[N];
%in.toWCharArray(str);
! PyObject* %out = PyUnicode_FromWideChar(str, N);
delete[] str;
return %out;
</native-to-target>
--- 194,202 ----
<native-to-target>
const int N = %in.length();
wchar_t* str = new wchar_t[N];
+ memset(str, 0, sizeof(wchar_t) * N);
%in.toWCharArray(str);
! PyObject* %out = PyUnicode_FromWideChar(str, N > 0 && str[N - 1] == 0 ? wcslen(str) : N);
delete[] str;
return %out;
</native-to-target>
***************
*** 225,236 ****
<primitive-type name="QStringRef">
<conversion-rule>
<native-to-target>
! const int N = %in.toString().length();
! wchar_t* str = new wchar_t[N];
! %in.toString().toWCharArray(str);
! PyObject* %out = PyUnicode_FromWideChar(str, N);
! delete[] str;
! return %out;
</native-to-target>
<target-to-native>
<add-conversion type="PyObject" check="Shiboken::String::check(%in) || %in == Py_None">
--- 226,232 ----
<primitive-type name="QStringRef">
<conversion-rule>
<native-to-target>
! return %CONVERTTOPYTHON[QString](%in.toString());
</native-to-target>
<target-to-native>
<add-conversion type="PyObject" check="Shiboken::String::check(%in) || %in == Py_None">
***************
*** 243,249 ****
<conversion-rule>
<native-to-target>
wchar_t c = (wchar_t)%in.unicode();
! return PyUnicode_FromWideChar(&c, 1);
</native-to-target>
<target-to-native>
<add-conversion type="PyString" check="Shiboken::String::checkChar(%in)">
--- 239,245 ----
<conversion-rule>
<native-to-target>
wchar_t c = (wchar_t)%in.unicode();
! return PyUnicode_FromWideChar(&c, c == 0 ? 0 : 1);
</native-to-target>
<target-to-native>
<add-conversion type="PyString" check="Shiboken::String::checkChar(%in)">
_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside