summaryrefslogtreecommitdiff
path: root/Objects/unicodeobject.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-10-09 03:17:30 +0200
committerVictor Stinner <victor.stinner@gmail.com>2015-10-09 03:17:30 +0200
commit797485e10135ca323565b22b4fabf1e161a5ec7a (patch)
treefb439a51835b26a3c5bf7c066d74e7a75ac83b10 /Objects/unicodeobject.c
parentb13b97d3b881daaab8f3bf32cc851eac9b895c52 (diff)
downloadcpython-git-797485e10135ca323565b22b4fabf1e161a5ec7a.tar.gz
Issue #25318: Avoid sprintf() in backslashreplace()
Rewrite backslashreplace() to be closer to PyCodec_BackslashReplaceErrors(). Add also unit tests for non-BMP characters.
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r--Objects/unicodeobject.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 614d2147cb..10cdcc0ec0 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -610,14 +610,25 @@ backslashreplace(_PyBytesWriter *writer, Py_ssize_t prealloc_per_char,
/* generate replacement */
for (i = collstart; i < collend; ++i) {
ch = PyUnicode_READ(kind, data, i);
- if (ch < 0x100)
- str += sprintf(str, "\\x%02x", ch);
- else if (ch < 0x10000)
- str += sprintf(str, "\\u%04x", ch);
- else {
- assert(ch <= MAX_UNICODE);
- str += sprintf(str, "\\U%08x", ch);
+ *str++ = '\\';
+ if (ch >= 0x00010000) {
+ *str++ = 'U';
+ *str++ = Py_hexdigits[(ch>>28)&0xf];
+ *str++ = Py_hexdigits[(ch>>24)&0xf];
+ *str++ = Py_hexdigits[(ch>>20)&0xf];
+ *str++ = Py_hexdigits[(ch>>16)&0xf];
+ *str++ = Py_hexdigits[(ch>>12)&0xf];
+ *str++ = Py_hexdigits[(ch>>8)&0xf];
+ }
+ else if (ch >= 0x100) {
+ *str++ = 'u';
+ *str++ = Py_hexdigits[(ch>>12)&0xf];
+ *str++ = Py_hexdigits[(ch>>8)&0xf];
}
+ else
+ *str++ = 'x';
+ *str++ = Py_hexdigits[(ch>>4)&0xf];
+ *str++ = Py_hexdigits[ch&0xf];
}
return str;
}