diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2009-01-13 22:59:11 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2009-01-13 22:59:11 (GMT) |
commit | 8d4e505aa8c916ba5c7da6a7374fb2e7b4b37af3 (patch) | |
tree | 790045025562d75fb4f34dfa822965916a354768 /Objects/stringlib | |
parent | b9d1a4ddc3da5611f37b60dc0fc887fb9ea48514 (diff) | |
download | cpython-8d4e505aa8c916ba5c7da6a7374fb2e7b4b37af3.zip cpython-8d4e505aa8c916ba5c7da6a7374fb2e7b4b37af3.tar.gz cpython-8d4e505aa8c916ba5c7da6a7374fb2e7b4b37af3.tar.bz2 |
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.
(*) or at least it is our interpretation
Diffstat (limited to 'Objects/stringlib')
-rw-r--r-- | Objects/stringlib/transmogrify.h | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index fe478c3..7dc8177 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; } |