summaryrefslogtreecommitdiffstats
path: root/Objects/stringlib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2009-01-13 22:59:11 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2009-01-13 22:59:11 (GMT)
commit8d4e505aa8c916ba5c7da6a7374fb2e7b4b37af3 (patch)
tree790045025562d75fb4f34dfa822965916a354768 /Objects/stringlib
parentb9d1a4ddc3da5611f37b60dc0fc887fb9ea48514 (diff)
downloadcpython-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.h67
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;
}