Mercurial > cpython-lru_cache-weakref
diff Objects/stringobject.c @ 50137:61d06409a660 2.4
Backported r55839 and r61350
Issue #4469: Prevent expandtabs() on string and unicode
objects from causing a segfault when a large width is passed
on 32-bit platforms.
| author | Martin v. Löwis <martin@v.loewis.de> |
|---|---|
| date | Sat, 13 Dec 2008 13:20:46 +0000 |
| parents | 200c8aab1917 |
| children |
line wrap: on
line diff
--- a/Objects/stringobject.c Sun Nov 30 13:33:28 2008 +0000 +++ b/Objects/stringobject.c Sat Dec 13 13:20:46 2008 +0000 @@ -2759,9 +2759,9 @@ static PyObject* string_expandtabs(PyStringObject *self, PyObject *args) { - const char *e, *p; + const char *e, *p, *qe; char *q; - int i, j; + int i, j, incr; PyObject *u; int tabsize = 8; @@ -2769,46 +2769,70 @@ return NULL; /* First pass: determine size of output string */ - i = j = 0; - e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); + i = 0; /* chars up to and including most recent \n or \r */ + j = 0; /* chars since most recent \n or \r (use in tab calculations) */ + e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); /* end of input */ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { - if (tabsize > 0) - j += tabsize - (j % tabsize); + if (tabsize > 0) { + incr = tabsize - (j % tabsize); + if (j > INT_MAX - incr) + goto overflow1; + j += incr; + } } else { + if (j > INT_MAX - 1) + goto overflow1; j++; if (*p == '\n' || *p == '\r') { + if (i > INT_MAX - j) + goto overflow1; i += j; j = 0; } } + if (i > INT_MAX - j) + goto overflow1; + /* Second pass: create output string and fill it */ u = PyString_FromStringAndSize(NULL, i + j); if (!u) return NULL; - j = 0; - q = PyString_AS_STRING(u); + j = 0; /* same as in first pass */ + q = PyString_AS_STRING(u); /* next output char */ + qe = PyString_AS_STRING(u) + PyString_GET_SIZE(u); /* end of output */ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); j += i; - while (i--) + while (i--) { + if (q >= qe) + goto overflow2; *q++ = ' '; + } } } else { + if (q >= qe) + goto overflow2; + *q++ = *p; j++; - *q++ = *p; if (*p == '\n' || *p == '\r') j = 0; } return u; + + overflow2: + Py_DECREF(u); + overflow1: + PyErr_SetString(PyExc_OverflowError, "new string is too long"); + return NULL; } static PyObject *
