@@ -8730,37 +8730,54 @@ formatchar(Py_UNICODE *buf,
87308730 size_t buflen ,
87318731 PyObject * v )
87328732{
8733- /* presume that the buffer is at least 2 characters long */
8733+ /* presume that the buffer is at least 3 characters long */
87348734 if (PyUnicode_Check (v )) {
8735- if (PyUnicode_GET_SIZE (v ) != 1 )
8736- goto onError ;
8737- buf [0 ] = PyUnicode_AS_UNICODE (v )[0 ];
8735+ if (PyUnicode_GET_SIZE (v ) == 1 ) {
8736+ buf [0 ] = PyUnicode_AS_UNICODE (v )[0 ];
8737+ buf [1 ] = '\0' ;
8738+ return 1 ;
8739+ }
8740+ #ifndef Py_UNICODE_WIDE
8741+ if (PyUnicode_GET_SIZE (v ) == 2 ) {
8742+ /* Decode a valid surrogate pair */
8743+ int c0 = PyUnicode_AS_UNICODE (v )[0 ];
8744+ int c1 = PyUnicode_AS_UNICODE (v )[1 ];
8745+ if (0xD800 <= c0 && c0 <= 0xDBFF &&
8746+ 0xDC00 <= c1 && c1 <= 0xDFFF ) {
8747+ buf [0 ] = c0 ;
8748+ buf [1 ] = c1 ;
8749+ buf [2 ] = '\0' ;
8750+ return 2 ;
8751+ }
8752+ }
8753+ #endif
8754+ goto onError ;
87388755 }
87398756 else {
87408757 /* Integer input truncated to a character */
87418758 long x ;
87428759 x = PyLong_AsLong (v );
87438760 if (x == -1 && PyErr_Occurred ())
87448761 goto onError ;
8745- #ifdef Py_UNICODE_WIDE
8762+
87468763 if (x < 0 || x > 0x10ffff ) {
87478764 PyErr_SetString (PyExc_OverflowError ,
8748- "%c arg not in range(0x110000) "
8749- "(wide Python build)" );
8765+ "%c arg not in range(0x110000)" );
87508766 return -1 ;
87518767 }
8752- #else
8753- if (x < 0 || x > 0xffff ) {
8754- PyErr_SetString (PyExc_OverflowError ,
8755- "%c arg not in range(0x10000) "
8756- "(narrow Python build)" );
8757- return -1 ;
8768+
8769+ #ifndef Py_UNICODE_WIDE
8770+ if (x > 0xffff ) {
8771+ x -= 0x10000 ;
8772+ buf [0 ] = (Py_UNICODE )(0xD800 | (x >> 10 ));
8773+ buf [1 ] = (Py_UNICODE )(0xDC00 | (x & 0x3FF ));
8774+ return 2 ;
87588775 }
87598776#endif
87608777 buf [0 ] = (Py_UNICODE ) x ;
8778+ buf [1 ] = '\0' ;
8779+ return 1 ;
87618780 }
8762- buf [1 ] = '\0' ;
8763- return 1 ;
87648781
87658782 onError :
87668783 PyErr_SetString (PyExc_TypeError ,
0 commit comments