diff options
author | Benjamin Peterson <benjamin@python.org> | 2014-03-30 23:47:57 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2014-03-30 23:47:57 (GMT) |
commit | 23cf403ca17dc1ac2eeccf7476a1ffd47ea88137 (patch) | |
tree | 9d4fad0587516c782983be927064c1e1e3ce915d | |
parent | cf25c5caae01b1e44793478df50456048e11f31b (diff) | |
download | cpython-23cf403ca17dc1ac2eeccf7476a1ffd47ea88137.zip cpython-23cf403ca17dc1ac2eeccf7476a1ffd47ea88137.tar.gz cpython-23cf403ca17dc1ac2eeccf7476a1ffd47ea88137.tar.bz2 |
fix expandtabs overflow detection to be consistent and not rely on signed overflow
-rw-r--r-- | Objects/stringlib/transmogrify.h | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index 1e132e5..be595a6 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -15,7 +15,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args) { const char *e, *p; char *q; - size_t i, j; + Py_ssize_t i, j; PyObject *u; int tabsize = 8; @@ -25,35 +25,31 @@ stringlib_expandtabs(PyObject *self, PyObject *args) /* First pass: determine size of output string */ i = j = 0; e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); - for (p = STRINGLIB_STR(self); p < e; p++) + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { - j += tabsize - (j % tabsize); - if (j > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } + Py_ssize_t incr = tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX - incr) + goto overflow; + j += incr; } } else { + if (j > PY_SSIZE_T_MAX - 1) + goto overflow; j++; if (*p == '\n' || *p == '\r') { + if (i > PY_SSIZE_T_MAX - j) + goto overflow; i += j; j = 0; - if (i > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } } } - - if ((i + j) > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, "result is too long"); - return NULL; } + if (i > PY_SSIZE_T_MAX - j) + goto overflow; + /* Second pass: create output string and fill it */ u = STRINGLIB_NEW(NULL, i + j); if (!u) @@ -62,7 +58,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args) j = 0; q = STRINGLIB_STR(u); - for (p = STRINGLIB_STR(self); p < e; p++) + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); @@ -77,8 +73,12 @@ stringlib_expandtabs(PyObject *self, PyObject *args) if (*p == '\n' || *p == '\r') j = 0; } - + } + return u; + overflow: + PyErr_SetString(PyExc_OverflowError, "result too long"); + return NULL; } Py_LOCAL_INLINE(PyObject *) |