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 &amp;&amp; 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(&amp;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(&amp;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

Reply via email to