From: Serhiy Storchaka Date: Sat, 4 Oct 2014 11:14:41 +0000 (+0300) Subject: Issue #22518: Fixed integer overflow issues in "backslashreplace" and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d524922bdc2b8db02df70ff10ccac0285dfa2014;p=python Issue #22518: Fixed integer overflow issues in "backslashreplace" and "xmlcharrefreplace" error handlers. --- diff --git a/Misc/NEWS b/Misc/NEWS index 0a97051afc..7b8177fc8a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 2.7.9? Core and Builtins ----------------- +- Issue #22518: Fixed integer overflow issues in "backslashreplace" and + "xmlcharrefreplace" error handlers. + - Issue #22526: Fix iterating through files with lines longer than 2^31 bytes. - Issue #22519: Fix overflow checking in PyString_Repr. diff --git a/Python/codecs.c b/Python/codecs.c index 7d1145f193..8b8c037e93 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -558,7 +558,7 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) Py_UNICODE *startp; Py_UNICODE *e; Py_UNICODE *outp; - int ressize; + Py_ssize_t ressize; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) @@ -566,6 +566,14 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; startp = PyUnicode_AS_UNICODE(object); + if (end - start > PY_SSIZE_T_MAX / (2+7+1)) { + end = start + PY_SSIZE_T_MAX / (2+7+1); +#ifndef Py_UNICODE_WIDE + ch = startp[end - 1]; + if (0xD800 <= ch && ch <= 0xDBFF) + end--; +#endif + } e = startp + end; for (p = startp+start, ressize = 0; p < e;) { Py_UCS4 ch = *p++; @@ -675,13 +683,15 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) Py_UNICODE *p; Py_UNICODE *startp; Py_UNICODE *outp; - int ressize; + Py_ssize_t ressize; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; + if (end - start > PY_SSIZE_T_MAX / (1+1+8)) + end = start + PY_SSIZE_T_MAX / (1+1+8); startp = PyUnicode_AS_UNICODE(object); for (p = startp+start, ressize = 0; p < startp+end; ++p) { #ifdef Py_UNICODE_WIDE