summaryrefslogtreecommitdiffstats
path: root/Objects/stringlib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2009-01-13 23:13:52 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2009-01-13 23:13:52 (GMT)
commitc2f02216b69b844e233a2bd86ba43508fee55c86 (patch)
tree9bb44dcd0f9f36f230b22d7e5ecf677ff2cf6228 /Objects/stringlib
parent3a5067c208dec1c702ae93aa26b03d5b0e7711ed (diff)
downloadcpython-c2f02216b69b844e233a2bd86ba43508fee55c86.zip
cpython-c2f02216b69b844e233a2bd86ba43508fee55c86.tar.gz
cpython-c2f02216b69b844e233a2bd86ba43508fee55c86.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.
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;
}