diff -r 76713f4d9f0f Lib/test/test_tcl.py
--- a/Lib/test/test_tcl.py Sun Feb 09 06:07:47 2014 -0800
+++ b/Lib/test/test_tcl.py Sun Feb 09 22:27:16 2014 +0200
@@ -341,7 +341,12 @@
self.assertEqual(passValue(True), True if self.wantobjects else '1')
self.assertEqual(passValue(False), False if self.wantobjects else '0')
self.assertEqual(passValue('string'), 'string')
+ self.assertEqual(passValue('string\xbd'), 'string\xbd')
self.assertEqual(passValue('string\u20ac'), 'string\u20ac')
+ self.assertEqual(passValue(b'string'), 'string')
+ self.assertEqual(passValue(b'string\xe2\x82\xac'), 'string\u20ac')
+ self.assertEqual(passValue('string\ud801'), 'string\ud801')
+ self.assertEqual(passValue('string\ud801\udca2'), 'string\ud801\udca2')
self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd')
self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac')
@@ -397,6 +402,12 @@
check('string\u20ac', 'string\u20ac')
check(b'string', 'string')
check(b'string\xe2\x82\xac', 'string\u20ac')
+ check('string\udca2', 'string\udced\udcb2\udca2')
+ check('string\ud801\udca2',
+ 'string\udced\udca0\udc81\udced\udcb2\udca2')
+ check(b'string\xed\xa0\x81', 'string\udced\udca0\udc81')
+ check(b'string\xed\xa0\x81\xed\xb2\xa2',
+ 'string\udced\udca0\udc81\udced\udcb2\udca2')
check('str\x00ing', 'str\x00ing')
check('str\x00ing\xbd', 'str\x00ing\xbd')
check('str\x00ing\u20ac', 'str\x00ing\u20ac')
diff -r 76713f4d9f0f Modules/_tkinter.c
--- a/Modules/_tkinter.c Sun Feb 09 06:07:47 2014 -0800
+++ b/Modules/_tkinter.c Sun Feb 09 22:27:16 2014 +0200
@@ -329,16 +329,16 @@
static PyObject *
-unicodeFromTclStringAndSize(const char *s, Py_ssize_t size)
+unicodeFromTclStringAndSize(const char *s, Py_ssize_t size, const char *errors)
{
PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL);
if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
+ char *buf = NULL;
+ PyErr_Clear();
/* Tcl encodes null character as \xc0\x80 */
if (memchr(s, '\xc0', size)) {
- char *buf, *q;
const char *e = s + size;
- PyErr_Clear();
- q = buf = (char *)PyMem_Malloc(size);
+ char *q = buf = (char *)PyMem_Malloc(size);
if (buf == NULL)
return NULL;
while (s != e) {
@@ -351,9 +351,10 @@
}
s = buf;
size = q - s;
- r = PyUnicode_DecodeUTF8(s, size, NULL);
+ }
+ r = PyUnicode_DecodeUTF8(s, size, errors);
+ if (buf != NULL)
PyMem_Free(buf);
- }
}
return r;
}
@@ -361,7 +362,7 @@
static PyObject *
unicodeFromTclString(const char *s)
{
- return unicodeFromTclStringAndSize(s, strlen(s));
+ return unicodeFromTclStringAndSize(s, strlen(s), NULL);
}
static PyObject *
@@ -369,7 +370,7 @@
{
int len;
char *s = Tcl_GetStringFromObj(value, &len);
- return unicodeFromTclStringAndSize(s, len);
+ return unicodeFromTclStringAndSize(s, len, NULL);
}
@@ -970,7 +971,7 @@
TkappObject *app = (TkappObject*)tkapp;
if (value->typePtr == NULL) {
- return unicodeFromTclStringAndSize(value->bytes, value->length);
+ return unicodeFromTclStringAndSize(value->bytes, value->length, NULL);
}
if (value->typePtr == app->BooleanType) {
@@ -1946,7 +1947,9 @@
return PythonCmd_Error(interp);
for (i = 0; i < (argc - 1); i++) {
- PyObject *s = unicodeFromTclString(argv[i + 1]);
+ PyObject *s = unicodeFromTclStringAndSize(argv[i + 1],
+ strlen(argv[i + 1]),
+ "surrogateescape");
if (!s || PyTuple_SetItem(arg, i, s)) {
Py_DECREF(arg);
return PythonCmd_Error(interp);