diff -r 19e199038704 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Tue Oct 25 15:38:28 2016 +0300 +++ b/Objects/unicodeobject.c Wed Oct 26 00:32:56 2016 +0800 @@ -4705,7 +4705,7 @@ Py_ssize_t len; PyObject *v; int inShift = 0; - Py_ssize_t i; + Py_ssize_t i, max_char_size; unsigned int base64bits = 0; unsigned long base64buffer = 0; char * out; @@ -4720,10 +4720,16 @@ if (len == 0) return PyBytes_FromStringAndSize(NULL, 0); - /* It might be possible to tighten this worst case */ - if (len > PY_SSIZE_T_MAX / 8) + if (kind == PyUnicode_1BYTE_KIND || kind == PyUnicode_2BYTE_KIND) { + max_char_size = 3; + } else { + assert(kind == PyUnicode_4BYTE_KIND); + max_char_size = 6; + } + if (len > (PY_SSIZE_T_MAX - 2)/ max_char_size) { return PyErr_NoMemory(); - v = PyBytes_FromStringAndSize(NULL, len * 8); + } + v = PyBytes_FromStringAndSize(NULL, len * max_char_size + 2); if (v == NULL) return NULL; @@ -4754,7 +4760,7 @@ else { /* not in a shift sequence */ if (ch == '+') { *out++ = '+'; - *out++ = '-'; + *out++ = '-'; } else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) { *out++ = (char) ch; @@ -4787,10 +4793,12 @@ base64bits -= 6; } } - if (base64bits) - *out++= TO_BASE64(base64buffer << (6-base64bits) ); - if (inShift) + if (inShift) { + if (base64bits) { + *out++= TO_BASE64(base64buffer << (6-base64bits)); + } *out++ = '-'; + } if (_PyBytes_Resize(&v, out - start) < 0) return NULL; return v;