[issue17137] Malfunctioning compiled code in Python 3.3 x64

STINNER Victor report at bugs.python.org
Thu Feb 7 17:19:51 CET 2013


STINNER Victor added the comment:

Ok, it's a bug in the function resize a compact Unicode string,
resize_compact(): wstr field is not updated to the new size.

Attached patch should fix it. The bug was introduced by me in Python 3.3.

I don't think that it's possible to resize wstr buffer instead of
freeing it: it will not be refilled by PyUnicode_AsUnicodeAndSize() if
wstr is not NULL. An alternative is to create a new string (instead of
using realloc) if wstr is not NULL.

2013/2/7 Florent Xicluna <report at bugs.python.org>:
>
> Changes by Florent Xicluna <florent.xicluna at gmail.com>:
>
>
> ----------
> components:  -Windows
>
> _______________________________________
> Python tracker <report at bugs.python.org>
> <http://bugs.python.org/issue17137>
> _______________________________________

----------
keywords: +patch
Added file: http://bugs.python.org/file28987/pep393.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue17137>
_______________________________________
-------------- next part --------------
diff -r b8a6bc70fc08 Lib/test/test_unicode.py
--- a/Lib/test/test_unicode.py	Thu Feb 07 17:05:32 2013 +0200
+++ b/Lib/test/test_unicode.py	Thu Feb 07 17:15:48 2013 +0100
@@ -7,6 +7,7 @@ Written by Marc-Andre Lemburg (mal at lembu
 """#"
 import _string
 import codecs
+import random
 import struct
 import sys
 import unittest
@@ -2191,6 +2192,20 @@ class UnicodeTest(string_tests.CommonTes
         self.assertEqual(args[0], text)
         self.assertEqual(len(args), 1)
 
+    def test_resize(self):
+        for length in range(1, 100, 7):
+            # generate a fresh string (refcount=1)
+            text = 'a' * length + 'b'
+
+            # fill wstr internal field
+            abc = text.encode('unicode_internal')
+            self.assertEqual(abc.decode('unicode_internal'), text)
+
+            text += 'c'
+            abcdef = text.encode('unicode_internal')
+            self.assertNotEqual(abc, abcdef)
+            self.assertEqual(abcdef.decode('unicode_internal'), text)
+
 
 class StringModuleTest(unittest.TestCase):
     def test_formatter_parser(self):
diff -r b8a6bc70fc08 Objects/unicodeobject.c
--- a/Objects/unicodeobject.c	Thu Feb 07 17:05:32 2013 +0200
+++ b/Objects/unicodeobject.c	Thu Feb 07 17:15:48 2013 +0100
@@ -717,6 +717,10 @@ resize_compact(PyObject *unicode, Py_ssi
         if (!PyUnicode_IS_ASCII(unicode))
             _PyUnicode_WSTR_LENGTH(unicode) = length;
     }
+    else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) {
+        PyObject_DEL(_PyUnicode_WSTR(unicode));
+        _PyUnicode_WSTR(unicode) = NULL;
+    }
 #ifdef Py_DEBUG
     unicode_fill_invalid(unicode, old_length);
 #endif


More information about the Python-bugs-list mailing list