From a1b22ce68c8c689f23746340bbb167186d5d24fa Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 13 Jan 2009 23:25:47 +0000 Subject: [PATCH] Merged revisions 68589 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r68589 | antoine.pitrou | 2009-01-14 00:13:52 +0100 (mer., 14 janv. 2009) | 5 lines Issue #4935: The overflow checking code in the expandtabs() method common to str, bytes and bytearray could be optimized away by the compiler, letting the interpreter segfault instead of raising an error. ........ --- Misc/NEWS | 4 ++ Objects/stringlib/transmogrify.h | 67 ++++++++++++++------------------ 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index b60384119f..055149259f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,10 @@ What's New in Python 2.6.2 Core and Builtins ----------------- +- Issue #4935: The overflow checking code in the expandtabs() method common + to str, bytes and bytearray could be optimized away by the compiler, letting + the interpreter segfault instead of raising an error. + - Issue #1180193: When importing a module from a .pyc (or .pyo) file with an existing .py counterpart, override the co_filename attributes of all code objects if the original filename is obsolete (which can happen if the diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index fe478c358c..7dc81776ab 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -22,76 +22,69 @@ stringlib_expandtabs(PyObject *self, PyObject *args) { const char *e, *p; char *q; - Py_ssize_t i, j, old_j; + size_t i, j; PyObject *u; int tabsize = 8; - + if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) - return NULL; - + return NULL; + /* First pass: determine size of output string */ - i = j = old_j = 0; + i = j = 0; e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); for (p = STRINGLIB_STR(self); p < e; p++) if (*p == '\t') { - if (tabsize > 0) { - j += tabsize - (j % tabsize); - /* XXX: this depends on a signed integer overflow to < 0 */ - /* C compilers, including gcc, do -NOT- guarantee this. */ - if (old_j > j) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } - old_j = j; + if (tabsize > 0) { + j += tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "result is too long"); + return NULL; + } } - } + } else { j++; if (*p == '\n' || *p == '\r') { i += j; - old_j = j = 0; - /* XXX: this depends on a signed integer overflow to < 0 */ - /* C compilers, including gcc, do -NOT- guarantee this. */ - if (i < 0) { + j = 0; + if (i > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "result is too long"); return NULL; } } } - - if ((i + j) < 0) { - /* XXX: this depends on a signed integer overflow to < 0 */ - /* C compilers, including gcc, do -NOT- guarantee this. */ + + if ((i + j) > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "result is too long"); return NULL; } - + /* Second pass: create output string and fill it */ u = STRINGLIB_NEW(NULL, i + j); if (!u) return NULL; - + j = 0; q = STRINGLIB_STR(u); - + for (p = STRINGLIB_STR(self); p < e; p++) if (*p == '\t') { - if (tabsize > 0) { - i = tabsize - (j % tabsize); - j += i; - while (i--) - *q++ = ' '; - } - } - else { + if (tabsize > 0) { + i = tabsize - (j % tabsize); + j += i; + while (i--) + *q++ = ' '; + } + } + else { j++; - *q++ = *p; + *q++ = *p; if (*p == '\n' || *p == '\r') j = 0; } - + return u; } -- 2.49.0