]> granicus.if.org Git - python/commitdiff
Fix PyUnicode_FromFormatV("%c") for non-BMP char
authorVictor Stinner <victor.stinner@haypocalc.com>
Mon, 21 Feb 2011 21:13:44 +0000 (21:13 +0000)
committerVictor Stinner <victor.stinner@haypocalc.com>
Mon, 21 Feb 2011 21:13:44 +0000 (21:13 +0000)
Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
narrow build.

Lib/test/test_unicode.py
Misc/NEWS
Objects/unicodeobject.c

index e2d67cd949cec5376803f9c4a07c7b4e21ceb1c3..9ad9eed6ac97d6350f584dbdc03042466cc5bce7 100644 (file)
@@ -1427,7 +1427,7 @@ class UnicodeTest(string_tests.CommonTest,
     # Test PyUnicode_FromFormat()
     def test_from_format(self):
         support.import_module('ctypes')
-        from ctypes import pythonapi, py_object
+        from ctypes import pythonapi, py_object, c_int
         if sys.maxunicode == 65535:
             name = "PyUnicodeUCS2_FromFormat"
         else:
@@ -1452,6 +1452,9 @@ class UnicodeTest(string_tests.CommonTest,
             'string, got a non-ASCII byte: 0xe9$',
             PyUnicode_FromFormat, b'unicode\xe9=%s', 'ascii')
 
+        self.assertEqual(PyUnicode_FromFormat(b'%c', c_int(0xabcd)), '\uabcd')
+        self.assertEqual(PyUnicode_FromFormat(b'%c', c_int(0x10ffff)), '\U0010ffff')
+
         # other tests
         text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
         self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
index 7b55d203a0123fff218d2cf0d71546922574b067..5f2f99c71da1e85fba30663822077a0626c0de03 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
 Core and Builtins
 -----------------
 
+- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
+  narrow build.
+
 - Issue #11168: Remove filename debug variable from PyEval_EvalFrameEx().
   It encoded the Unicode filename to UTF-8, but the encoding fails on
   undecodable filename (on surrogate characters) which raises an unexpected
index 069be7b6c63e1def01dd96c3e404ce15be889516..57baebd54710186e79dd3bc8cf498497af27c991 100644 (file)
@@ -813,8 +813,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
 
             switch (*f) {
             case 'c':
+            {
+#ifndef Py_UNICODE_WIDE
+                int ordinal = va_arg(count, int);
+                if (ordinal > 0xffff)
+                    n += 2;
+                else
+                    n++;
+#else
                 (void)va_arg(count, int);
-                /* fall through... */
+                n++;
+#endif
+                break;
+            }
             case '%':
                 n++;
                 break;
@@ -992,8 +1003,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
 
             switch (*f) {
             case 'c':
-                *s++ = va_arg(vargs, int);
+            {
+                int ordinal = va_arg(vargs, int);
+#ifndef Py_UNICODE_WIDE
+                if (ordinal > 0xffff) {
+                    ordinal -= 0x10000;
+                    *s++ = 0xD800 | (ordinal >> 10);
+                    *s++ = 0xDC00 | (ordinal & 0x3FF);
+                } else
+#endif
+                *s++ = ordinal;
                 break;
+            }
             case 'd':
                 makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
                         width, precision, 'd');